Por que o node.js é asynchronous?

Ninguém realmente perguntou isso (de todas as “sugestões” que estou recebendo e também da pesquisa antes de perguntar aqui).

Então, por que o node.js é asynchronous?

Pelo que deduzi depois de alguma pesquisa:

Idiomas como PHP e Python são linguagens de script (posso estar errado sobre as linguagens reais que são linguagens de script) enquanto o JavaScript não é. (Eu suponho que isso deriva do fato de que JS não compila?)

O Node.js é executado em um único encadeamento, enquanto as linguagens de script usam vários encadeamentos.

Assíncrono significa sem estado e que a conexão é persistente enquanto síncrona é o (quase) oposto.

Talvez a resposta seja encontrada em algum lugar acima, mas ainda não tenho certeza.

Minha segunda e última pergunta relacionada a este tópico é esta:

JavaScript poderia ser transformado em uma linguagem síncrona?

PS. Eu sei que alguns de vocês vão perguntar “por que você quer fazer JS síncrono?” em suas respostas, mas a verdade é que eu não sei. Só estou fazendo esse tipo de pergunta porque tenho certeza de que há mais pessoas lá fora do que eu mesmo que pensaram sobre essas questões.

O Node.js é executado em um único encadeamento, enquanto as linguagens de script usam vários encadeamentos.

Não tecnicamente. O Node.js usa vários encadeamentos, mas apenas um encadeamento de execução. Os threads de segundo plano são para lidar com IO para fazer todo o trabalho de bondade assíncrona. Lidar com threads eficientemente é uma dor real, então a próxima melhor opção é rodar em um loop de events para que o código possa ser executado enquanto os threads em segundo plano são bloqueados no IO.

Assíncrono significa sem estado e que a conexão é persistente enquanto síncrona é o (quase) oposto.

Não necessariamente. Você pode preservar o estado em um sistema asynchronous com bastante facilidade. Por exemplo, em Javascript, você pode usar bind() para associar this a uma function, preservando assim o estado explicitamente quando a function retornar:

 function State() { // make sure that whenever doStuff is called it maintains its state this.doStuff = this.doStuff.bind(this); } State.prototype.doStuff = function () { }; 

Assíncrono significa não aguardar a conclusão de uma operação, mas sim registrar um ouvinte. Isso acontece o tempo todo em outros idiomas, principalmente qualquer coisa que precise aceitar a input do usuário. Por exemplo, em uma GUI Java, você não bloqueia a espera para o usuário pressionar um botão, mas registra um ouvinte com a GUI.

Minha segunda e última pergunta relacionada a este tópico é esta:

JavaScript poderia ser transformado em uma linguagem síncrona?

Tecnicamente, todas as linguagens são síncronas, até mesmo Javascript. No entanto, o JavaScript funciona muito melhor em um design asynchronous porque ele foi projetado para ser single threaded.

Basicamente, existem dois tipos de programas:

  • Limite de CPU – a única maneira de torná-lo mais rápido é obter mais tempo de CPU
  • IO bound- passa muito tempo esperando por dados, então um processador mais rápido não importa

Videogames, trituradores de números e compiladores são vinculados à CPU, enquanto os servidores da Web e GUIs geralmente são vinculados a E / S. O JavaScript é relativamente lento (por causa de sua complexidade), portanto, ele não seria capaz de competir em um cenário vinculado à CPU (confie em mim, escrevi meu quinhão de JavaScript vinculado à CPU).

Em vez de codificar em termos de classs e objects, o JavaScript se presta a codificação em termos de funções simples que podem ser agrupadas. Isso funciona muito bem no design asynchronous, porque os algoritmos podem ser gravados para processar os dados de forma incremental à medida que aparecem. O IO (especialmente IO de rede) é muito lento, portanto, há bastante tempo entre os pacotes de dados.

Exemplo

Vamos supor que você tenha 1000 conexões ativas, cada uma entregando um pacote a cada milissegundo, e o processamento de cada pacote leva 1 microssegundo (muito razoável). Vamos supor também que cada conexão envie 5 pacotes.

Em um aplicativo síncrono de encadeamento único, cada conexão será manipulada em série. O tempo total gasto é (5 * 1 + 5 * 0,001) * 1000 milissegundos ou ~ 5005 milissegundos.

Em um aplicativo asynchronous de encadeamento único, cada conexão será tratada em paralelo. Como cada pacote leva 1 milissegundo e o processamento de cada pacote leva 0,001 milissegundos, podemos processar cada pacote de conexão entre pacotes, de modo que nossa fórmula se torne: 1000 * .001 + 5 * 1 milissegundos ou ~ 6 milissegundos.

A solução tradicional para esse problema foi criar mais threads. Isso resolveu o problema de IO, mas quando o número de conexões subiu, o uso de memory também aumentou (threads custam muita memory) e o uso da CPU (multiplexar 100 threads em 1 core é mais difícil que 1 thread em 1 core).

No entanto, existem desvantagens. Se o seu aplicativo da Web também precisar fazer alguns cálculos pesados, você é SOL porque, enquanto processa números, as conexões precisam aguardar. O encadeamento resolve isso porque o sistema operacional pode trocar sua tarefa com uso intenso da CPU quando os dados estão prontos para um encadeamento aguardando o IO. Além disso, node.js está vinculado a um único núcleo, portanto, você não pode tirar vantagem de seu processador de vários núcleos, a menos que você gire várias instâncias e solicitações de proxy.

Javascript não compila em nada. É “avaliado” em tempo de execução, assim como o PHP e o Ruby. Portanto, é uma linguagem de script como o PHP / Ruby. (seu nome oficial é, na verdade, ECMAScript).

O ‘modelo’ ao qual o Node adere é um pouco diferente do PHP / Ruby. O Node.js usa um ‘loop de events’ (o único segmento) que tem o único objective de receber solicitações de rede e manipulá-las rapidamente, e se por algum motivo encontrar uma operação que demore (solicitação de API, consulta de database – basicamente qualquer coisa envolvendo IO (input / saída)) passa isso para um thread ‘worker’ de plano de fundo e sai para fazer outra coisa enquanto o thread de trabalho aguarda a conclusão da tarefa longa. Quando isso acontece, o principal ‘loop de events’ recebe os resultados e continua lidando com eles.

PHP / Ruby seguindo um modelo de threading. Essencialmente, para cada solicitação de rede de input, o servidor de aplicativos gera um thread ou processo isloated para manipular a solicitação. Isso não se adapta muito bem e a abordagem do Node é citada como um de seus principais pontos fortes em comparação com esse modelo.

Assíncrono significa sem estado e que a conexão é persistente enquanto síncrona é o (quase) oposto.

Não. As instruções síncronas são concluídas em uma ordem natural, do primeiro ao último. Instruções assíncronas significam que se uma etapa no stream de um programa demorar um tempo relativamente longo, o programa continuará executando as operações e simplesmente retornará a esta operação quando estiver concluída.

JavaScript poderia ser transformado em uma linguagem síncrona?

Certas operações no JavaScript são síncronas. Outros são asynchronouss. Por exemplo:

Operações de bloqueio:

 for(var k = 0; k < 1; k = k - 1;){ alert('this will quickly get annoying and the loop will block execution') alert('this is blocked and will never happen because the above loop is infinite'); 

Assíncrono:

 jQuery.get('/foo', function (result) { alert('This will occur 2nd, asynchronously'); }); alert('This will occur 1st. The above operation was skipped over and execution continued until the above operation completes.'); 

JavaScript poderia ser transformado em uma linguagem síncrona?

Javascript não é uma “linguagem assíncrona”; em vez disso, node.js tem muitas APIs assíncronas. Asynchronous-ness é uma propriedade da API e não da linguagem. A facilidade com que as funções podem ser criadas e transmitidas em JavaScript torna conveniente passar funções de retorno de chamada, que é uma maneira de manipular o stream de controle em uma API assíncrona, mas não há nada inerentemente asynchronous sobre o JavaScript . O Javascript pode suportar facilmente APIs síncronas.

Por que o node.js é asynchronous?

O Node.js favorece APIs assíncronas porque é single-threaded. Isso permite que ele gerencie com eficiência seus próprios resources, mas exige que operações de longa duração não sejam bloqueadas e APIs assíncronas são uma maneira de permitir o controle de stream com muitas operações sem bloqueio.