Como o JavaScript é executado em um único thread, depois que uma solicitação AJAX é feita, o que realmente acontece em segundo plano? Eu gostaria de ter uma visão mais profunda disso, alguém pode lançar alguma luz?
Como o JavaScript é executado em um único thread, depois que uma solicitação AJAX é feita, o que realmente acontece em segundo plano? Eu gostaria de ter uma visão mais profunda disso, alguém pode lançar alguma luz?
Respostas:
Abaixo das capas, o javascript tem uma fila de eventos. Sempre que um encadeamento de execução javascript termina, ele verifica se há outro evento na fila para processar. Se houver, ele sai da fila e aciona esse evento (como um clique do mouse, por exemplo).
A rede de código nativo que fica sob a chamada ajax saberá quando a resposta ajax for concluída e um evento será adicionado à fila de eventos javascript. Como o código nativo sabe quando a chamada ajax é feita depende da implementação. Pode ser implementado com threads ou também pode ser orientado por eventos (isso realmente não importa). O ponto da implementação é que, quando a resposta do ajax for concluída, algum código nativo saberá que foi feito e colocará um evento na fila JS.
Se nenhum Javascript estiver em execução no momento, o evento será acionado imediatamente, o que executará o manipulador de resposta ajax. Se algo estiver em execução no momento, o evento será processado quando o segmento de execução javascript atual terminar. Não é necessário realizar nenhuma pesquisa pelo mecanismo javascript. Quando uma parte do Javascript termina a execução, o mecanismo JS apenas verifica a fila de eventos para ver se há mais alguma coisa que precisa ser executada. Nesse caso, ele remove o próximo evento da fila e o executa (chamando uma ou mais funções de retorno de chamada registradas para esse evento). Se nada estiver na fila de eventos, o interpretador JS terá tempo livre (coleta de lixo ou inativo) até que um agente externo coloque outra coisa na fila de eventos e a ative novamente.
Como todos os eventos externos passam pela fila de eventos e nenhum evento é acionado enquanto o javascript está executando outra coisa, ele permanece com um único encadeamento.
Aqui estão alguns artigos sobre os detalhes:
.focus()
um item e isso aciona alguns outros eventos, como um evento de "desfoque" no item com foco. Esse evento de desfoque ocorre de forma síncrona e não passa pela fila de eventos, portanto aconteceria imediatamente antes de outras coisas que possam estar na fila de eventos. Na prática, nunca achei que isso fosse uma preocupação prática.
Você pode encontrar aqui uma documentação muito completa sobre manipulação de eventos em javascript.
Foi escrito por um cara que trabalha na implementação de javascript no Navegador Opera.
Mais precisamente, observe os títulos: "Fluxo de Eventos", "Fila de Eventos" e "Eventos Não-Usuário": você aprenderá que:
Nota: O link original era: link , mas agora está morto.
Quero elaborar um pouco sobre a implementação do ajax mencionada nas respostas.
Embora a execução Javascript (regular) não seja multiencadeada - como observado nas respostas acima - no entanto , o tratamento real do AJAX responses
(assim como o tratamento de solicitações) não é Javascript e, geralmente - é multiencadeado. (consulte implementação da fonte de cromo de XMLHttpRequest na que discutiremos acima)
e eu vou explicar, vamos pegar o seguinte código:
var xhr = new XMLHttpRequest();
var t = Date.now;
xhr.open( "GET", "https://swx.cdn.skype.com/shared/v/1.2.15/SkypeBootstrap.min.js?v="+t(), true );
xhr.onload = function( e ) {
console.log(t() + ': step 3');
alert(this.response.substr(0,20));
};
console.log(t() + ': step 1');
xhr.send();
console.log(t() + ': step 2');
after an AJAX request is made
(- após a etapa 1), enquanto o código js continua em execução (etapas 2 e depois), o navegador inicia o trabalho real de: 1. formatar uma solicitação tcp 2. abrir um soquete 3. enviar cabeçalhos 4. handshaking 5. enviar corpo 6. resposta em espera 7. cabeçalhos de leitura 8. corpo de leitura etc. toda essa implementação geralmente é executada em um encadeamento diferente, paralelamente à execução do código js. por exemplo, a implementação de cromo mencionada usa o Threadable Loader para digg-into 😉 (você também pode obter alguma impressão olhando a guia de rede de um carregamento de página, verá algumas solicitações simultâneas).
em conclusão, eu diria que - pelo menos - a maioria das operações de E / S pode ser feita simultaneamente / assíncrona (e você pode tirar proveito disso usando uma espera por exemplo). mas toda a interação com essas operações (a emissão, a execução do retorno de chamada js) é síncrona.