Eu tenho um widget JavaScript que fornece pontos de extensão padrão. Um deles é a beforecreate
função. Ele deve retornar false
para impedir que um item seja criado.
Eu adicionei uma chamada Ajax nessa função usando jQuery:
beforecreate: function (node, targetNode, type, to) {
jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),
function (result) {
if (result.isOk == false)
alert(result.message);
});
}
Mas quero impedir que meu widget crie o item, por isso devo retornar false
na função mãe, não no retorno de chamada. Existe uma maneira de executar uma solicitação AJAX síncrona usando jQuery ou qualquer outra API do navegador?
javascript
jquery
ajax
asynchronous
Artem Tikhomirov
fonte
fonte
beforecreate
.Respostas:
Na documentação do jQuery : você especifica a opção assíncrona como false para obter uma solicitação Ajax síncrona. Em seguida, seu retorno de chamada pode definir alguns dados antes que a função de sua mãe continue.
Aqui está a aparência do seu código se alterado conforme sugerido:
fonte
async: false
ainda é suportado no jQuery> = 1.8. A capacidade de usarasync: false
com jqXHR ($.Deferred
) é o que foi preterido. Em outras palavras, é necessário usar as opções mais recentes de sucesso / erro / retorno de chamada completo, em vez dos métodos herdados, por exemplojqXHR.done()
,.Você pode colocar a configuração do Ajax do jQuery no modo síncrono chamando
E depois faça suas chamadas Ajax usando
jQuery.get( ... );
Em seguida, basta ligá-lo novamente uma vez
Eu acho que funciona da mesma maneira sugerida por @Adam, mas pode ser útil para alguém que deseja reconfigurar sua sintaxe
jQuery.get()
oujQuery.post()
para ajQuery.ajax()
sintaxe mais elaborada .fonte
$.ajax()
". ;)Excelente solução! Percebi quando tentei implementá-lo que, se eu retornasse um valor na cláusula de sucesso, ele retornaria como indefinido. Eu tive que armazená-lo em uma variável e retornar essa variável. Este é o método que eu criei:
fonte
getWhatever
. Assim, você retornou nada ou seja,undefined
a partir do seugetWhatever
.Todas essas respostas perdem o ponto de que fazer uma chamada do Ajax com async: false fará com que o navegador seja interrompido até que a solicitação do Ajax seja concluída. O uso de uma biblioteca de controle de fluxo resolverá esse problema sem desligar o navegador. Aqui está um exemplo com o Frame.js :
fonte
fonte
getURL
vsget
? Por que alguém desliga meu navegador?" etcNota: Você não deve usar
async: false
devido a estas mensagens de aviso:O Chrome até alerta sobre isso no console:
Isso pode danificar sua página se você estiver fazendo algo assim, pois pode parar de funcionar a qualquer dia.
Se você quiser fazê-lo de uma maneira que ainda pareça síncrona, mas ainda não bloqueie, use async / waitit e provavelmente também algum ajax baseado em promessas como a nova API de busca
O chrome de edição está trabalhando em Desabilitar a sincronização XHR na dispensa de página quando a página está sendo navegada ou fechada pelo usuário. Isso envolve antes de descarregar, descarregar, ocultar página e alterar a visibilidade.
se esse for o seu caso de uso, convém dar uma olhada em navigator.sendBeacon vez
Também é possível que a página desative a sincronização necessária com os cabeçalhos http ou o atributo de permissão do iframe
fonte
await fetch(url)
chamada em umtry... catch
bloco para detectar erros assíncronos.async
no início, assim que você poderia apenas fazerfoo().catch(...)
para pegá-lo tambémbeforeunload
mas depois reverteu a alteração após feedback negativo bugs.chromium.org/p/chromium/issues/detail?id=952452Lembre-se de que, se você estiver fazendo uma chamada Ajax entre domínios (usando JSONP ) - não poderá fazê-lo de forma síncrona, o
async
sinalizador será ignorado pelo jQuery.Para chamadas JSONP, você pode usar:
fonte
Com
async: false
você obtém um navegador bloqueado. Para uma solução síncrona sem bloqueio, você pode usar o seguinte:ES6 / ECMAScript2015
Com o ES6, você pode usar um gerador e a co-biblioteca :
ES7
Com o ES7, você pode simplesmente usar o asyc waitit:
fonte
async function
para beforecreatebeforecreate: async function(....
e retire a auto invocado função asyncUsei a resposta dada por Carcione e a modifiquei para usar JSON.
Adicionei o dataType de 'JSON' e alterei o .responseText para responseJSON .
Também recuperei o status usando a propriedade statusText do objeto retornado. Observe que esse é o status da resposta do Ajax, não se o JSON é válido.
O back-end deve retornar a resposta em JSON correto (bem formado), caso contrário, o objeto retornado será indefinido.
Há dois aspectos a serem considerados ao responder à pergunta original. Um deles está dizendo ao Ajax para executar de forma síncrona (configurando async: false ) e o outro está retornando a resposta por meio da instrução de retorno da função de chamada, em vez de uma função de retorno de chamada.
Eu também tentei com o POST e funcionou.
Mudei o GET para POST e adicionei dados: postdata
Observe que o código acima funciona apenas no caso em que async é falso . Se você configurasse async: true, o objeto retornado jqxhr não seria válido no momento em que a chamada AJAX retornasse, somente mais tarde quando a chamada assíncrona for concluída, mas é tarde demais para definir a variável de resposta .
fonte
Este é um exemplo:
fonte
async false
com uma solução baseada em promessa. Isso apenas bloqueia o navegador sem nenhum benefício.ajax
chamadas já retornam) e.then()
oudone()
(como já mostra). Bloquear o navegador é uma experiência muito ruim para o usuário. Como eu disse, terasync: false
neste exemplo é uma completa perda de tempo.Primeiro devemos entender quando usamos $ .ajax e quando usamos $ .get / $. Post
Quando exigimos um controle de baixo nível sobre a solicitação ajax, como configurações de cabeçalho de solicitação, configurações de cache, configurações síncronas etc., então devemos optar por $ .ajax.
$ .get / $. post: quando não exigimos controle de baixo nível sobre a solicitação ajax. Apenas é simples obter / publicar os dados no servidor. É taquigrafia de
e, portanto, não podemos usar outros recursos (sincronização, cache etc.) com $ .get / $. post.
Portanto, para controle de baixo nível (sincronização, cache, etc.) Sobre solicitação ajax, devemos optar por $ .ajax
fonte
esta é minha implementação simples para solicitações ASYNC com jQuery. Espero que isso ajude alguém.
fonte
Como a
XMLHttpReponse
operação síncrona está obsoleta, eu vim com a seguinte solução que envolveXMLHttpRequest
. Isso permite consultas AJAX ordenadas enquanto ainda é de natureza assíncrona, o que é muito útil para tokens CSRF de uso único.Também é transparente, de modo que bibliotecas como o jQuery operam sem problemas.
fonte
Como a pergunta original era sobre
jQuery.get
, vale a pena mencionar aqui que (como mencionado aqui ) alguém poderia usá-loasync: false
de uma maneira ideal,$.get()
mas evitá- lo, pois o assíncronoXMLHTTPRequest
está obsoleto (e o navegador pode emitir um aviso):fonte
Defina
asyn:false
na solicitação ajax para torná-lo síncrono.Aqui está o exemplo de código:
Isso pode deixar a tela sem resposta.
fonte