O que determina quais funções Javascript estão bloqueando versus não bloqueando?

27

Faço Javascript com base na Web (vanilla JS, jQuery, Backbone, etc.) há alguns anos e, recentemente, venho trabalhando com o Node.js. Demorei um pouco para entender a programação "sem bloqueio", mas agora me acostumei a usar retornos de chamada para operações de IO e outros enfeites.

Entendo que o Javascript é único por natureza. Eu entendo o conceito do nó "fila de eventos". O que eu não entendo é o que determina se uma operação javascript individual está "bloqueando" versus "não bloqueando". Como sei de quais operações posso confiar para produzir uma saída de forma síncrona para uso em códigos posteriores e quais eu precisarei transmitir retornos de chamada para poder processar a saída após a conclusão da operação inicial? Existe uma lista de funções Javascript em algum lugar assíncrono / sem bloqueio e uma lista de funções síncronas / bloqueando? O que está impedindo meu aplicativo Javascript de ser uma condição de corrida gigante?

Sei que operações que demoram muito tempo, como operações de E / S em operações de Nó e AJAX na Web, exigem que sejam assíncronas e, portanto, usem retornos de chamada - mas quem está determinando o que qualifica como "muito tempo"? Existe algum tipo de gatilho nessas operações que as remove da "fila de eventos" normal? Caso contrário, o que os diferencia de operações simples, como atribuir valores a variáveis ​​ou fazer loop em matrizes, das quais parece que podemos confiar para concluir de maneira síncrona?

Talvez eu nem esteja pensando nisso corretamente - esperando que alguém possa me esclarecer. Obrigado!

Sean
fonte
isso é algo que eu achei realmente útil, mesmo que sua resposta à sua pergunta seja que você precisa verificar a documentação para descobrir se os métodos são assíncronos.
Anastasios Andronidis

Respostas:

13

Em geral, qualquer função que faça networking ou use temporizadores para fazer as coisas durante um período será assíncrona.

Se a função receber um retorno de chamada, é possível verificar para que serve o retorno de chamada e, geralmente, será óbvio se é assíncrono ou não. Se a função não oferecer um retorno de chamada, não haverá como comunicar resultados assíncronos, portanto provavelmente não é assíncrona.

Não há uma maneira rígida de dizer com certeza. Ele deve ser explicitado no documento para uma função ou óbvio pela forma como a interface funciona.

As operações assíncronas são diferentes nas manobras e as operações síncronas, pois as operações assíncronas têm a noção de configurar uma operação, iniciar a operação e depois ser notificado mais tarde sobre o andamento, conclusão ou erros na operação. Iterar uma matriz é uma operação síncrona. Não possui nenhum desses problemas. O código é executado de forma síncrona. A emissão de uma chamada ajax consiste em registrar um retorno de chamada para notificações de estado, iniciar a chamada ajax, continuar a executar outro javascript e, algum tempo depois, o retorno de chamada é chamado com uma alteração de estado na chamada ajax (como conclusão).

jfriend00
fonte
1
Como observação adicional, algumas funções Javascript estão bloqueando e não bloqueando, dependendo de seus parâmetros. Por exemplo, XMLHttpRequest.openpossui um asyncparâmetro booleano que controla se a chamada posterior sendé assíncrona.
19713 Brian
Eu simplesmente não achei esta resposta útil e, em geral, expliquei.
Mehdi Raash 23/02
@MehdiRaash - A resposta é que você descobre a partir da documentação ou da interface. Não há outro caminho. É o que isso diz. Não tenho certeza do que mais você estava esperando. Não existe uma resposta mágica à bala.
jfriend00
6

Pelo que entendi, você não está perguntando sobre o que deve tornar assíncrono, mas como saber se uma função é assíncrona.

Você verifica a documentação. Sério - é para isso que serve. Você não adivinha o que uma função faz com base no nome ou no contexto assim. Se você não tem certeza e tem acesso ao seu código-fonte, verifique isso.

Essa é a única maneira completamente confiável.

Agora, para adivinhar.

  • Se ele aceitar um retorno de chamada ou retornar uma promessa, provavelmente é assíncrono (vi exceções para essa regra)
  • Geralmente tudo o que está relacionado à E / S no node.js e mais geralmente no JavaScript é feito de forma assíncrona (também vi exceções a essa regra)
Benjamin Gruenbaum
fonte
4

Como o JavaScript é único, todos os blocos de processamento são encadeados até que um dos seguintes ocorra

1) A execução atual solicita um serviço externo, como uma solicitação de E / S ou de rede ou uma solicitação de webworker

2) Uma chamada de função é colocada em um timer para ser executada posteriormente

Não há lista de funções de bloqueio / não-bloqueio. Você deve verificar a documentação.

Seu aplicativo pode encontrar uma condição de corrida se vários serviços externos tiverem um bloqueio no encadeamento javascript e tentar acessá-lo ao mesmo tempo. Navegadores modernos e o mecanismo V8 lidam com isso, mas você pode encontrar essa condição de corrida se usar o phonegap e escrever aplicativos javascript para dispositivos móveis. O suporte não existe para lidar com essas condições de corrida.

Em geral, assuma os blocos de código, a menos que haja um retorno de chamada. E mesmo se houver um retorno de chamada, isso não significa que não será bloqueado.

codificador
fonte
-1

Eu também sou novo no node.js (e JavaScript em geral) e não estou acostumado a tanto código assíncrono. Eu só queria salientar que na Visão geral do bloqueio versus não bloqueio no nodejs.org , afirma que:

Todos os métodos de E / S na biblioteca padrão do Node.js. fornecem versões assíncronas, sem bloqueio, e aceitam funções de retorno de chamada. Alguns métodos também têm contrapartes de bloqueio, que têm nomes que terminam com Sincronização.

TaborKelly
fonte
1
como isso resolve a questão? Veja como responder
gnat