simulando um XMLHttpRequest síncrona
-
05-07-2019 - |
Pergunta
Eu li algumas das outras questões relacionadas ( Teste padrão para envolver uma função Asynchronous JavaScript para torná-lo síncrona & Faça evento assíncrono síncrono em JavaScript e pode haver mais), mas eu só quero ter a certeza de esgotar todas as possibilidades.
Seria possível "converter" um XMLHttpRequest assíncrona em um quase-síncrono usando setInterval ou setTimeout?
A idéia é que após o sucesso do Ajax solicitar uma variável será definido, que será o sinal por um tempo loop (que tem chamado tanto setInterval ou setTimeout, e uma função de chamada de retorno, conforme apropriado) para sair. Ou eu sou fundamentalmente mal-entendido as habilidades (ou limitações?) De setInterval e / ou setTimeout?
Solução
É verdade, você não quer usar setInterval e setTimeout na forma como você descreveu. O que você realmente quer fazer é apenas se sentir confortável com funções aninhadas, onde você pode escrever de uma forma mais ou menos síncrona.
Por exemplo:
XHR.get(your_data, function()
{
//what you would have done "synchronously"
});
Enquanto você pode usar setInterval e / ou setTimeout (com chamadas para setTimeout novamente no corpo da função) para "poll" para um código de sucesso, essa abordagem é drasticamente inferior apenas para lidar com a chamada de retorno em primeiro lugar em vez de voto para isto. Ele apresenta latência, foge com a CPU, e não escala em várias solicitações XHR, para citar algumas deficiências.
XHR vai chamar sua função quando ela for concluída, não faz muito sentido para executar uma função perguntando: "Será que estamos feito ainda? Será que estamos ainda feito?" enquanto isso. Por outro lado, se existe algum comportamento periódico que você está querendo bloquear até que a resposta vem de volta (um pedaço de animação que as necessidades que os dados para ser executado, por exemplo), é totalmente aceitável para cercar o código de bloqueio em uma instrução if:
var tick = window.setTimeout(tock, 20);
var tock = function()
{
if (response_done)
{
// dependent code
}
tick = window.setTimeout(tock, 20);
}
XHR.get(your_data, function() { /*Handle response*/ response_done = true; });
Outras dicas
Se eu estou recebendo a sua pergunta certa, você poderia conseguir um efeito semelhante usando o seguinte código:
var computationInterval =
window.setInterval(function() {
// do a computation cycle, as if you're in the body of a while loop
}, 100);
$.get('http://example.com/areWeThereYet', function() {
// break the intervals (the pseudo-cycle)
window.clearInterval(computationInterval);
});