Eu tenho lido nodebeginner E me deparei com os dois seguintes códigos.
O primeiro:
var result = database.query("SELECT * FROM hugetable"); console.log("Hello World");
O segundo:
database.query("SELECT * FROM hugetable", function(rows) { var result = rows; }); console.log("Hello World");
Eu entendo o que eles devem fazer, eles consultam o database para recuperar a resposta para a consulta. E então console.log('Hello world')
.
O primeiro deles é supostamente um código síncrono. E o segundo é um código asynchronous.
A diferença entre as duas peças é muito vaga para mim. Qual seria o resultado?
Pesquisando em programação assíncrona também não me ajudou.
A diferença é que no primeiro exemplo , o programa irá bloquear na primeira linha. A próxima linha ( console.log
) terá que esperar.
No segundo exemplo , o console.log
será executado enquanto a consulta estiver sendo processada. Ou seja, a consulta será processada em segundo plano, enquanto o programa está fazendo outras coisas e, quando os dados da consulta estiverem prontos, você fará o que quiser com ela.
Então, em poucas palavras: o primeiro exemplo irá bloquear, enquanto o segundo não será.
A saída dos dois exemplos a seguir:
// Example 1 - Synchronous (blocks) var result = database.query("SELECT * FROM hugetable"); console.log("Query finished"); console.log("Next line"); // Example 2 - Asynchronous (doesn't block) database.query("SELECT * FROM hugetable", function(result) { console.log("Query finished"); }); console.log("Next line");
Seria:
Query finished
Next line
Next line
Query finished
Nota
Enquanto o próprio nó é único encadeado , existem algumas tarefas que podem ser executadas em paralelo. Por exemplo, as operações do sistema de arquivos ocorrem em um processo diferente.
É por isso que o Node pode fazer operações assíncronas: um thread está fazendo operações do sistema de arquivos, enquanto o thread principal do Node continua executando seu código javascript. Em um servidor orientado a events como o Nó, o encadeamento do sistema de arquivos notifica o encadeamento do Nó principal de determinados events, como conclusão, falha ou progresso, juntamente com quaisquer dados associados a esse evento (como o resultado de uma consulta ao database ou um erro mensagem) eo thread principal do Node decide o que fazer com esses dados.
Você pode ler mais sobre isso aqui: Como o modelo de E / S único não segmentado funciona no Node.js
A diferença entre essas duas abordagens é a seguinte:
Modo síncrono: Aguarda que cada operação seja concluída, depois disso só executa a próxima operação. Para sua consulta: O comando console.log()
não será executado até & a menos que a consulta tenha terminado de executar para obter todo o resultado do Banco de Dados.
Modo asynchronous: Ele nunca espera que cada operação seja concluída, em vez disso, executa todas as operações apenas no primeiro GO. O resultado de cada operação será tratado assim que o resultado estiver disponível. Para sua consulta: O comando console.log()
será executado logo após o método Database.Query()
. Enquanto a consulta do Banco de Dados é executada em segundo plano e carrega o resultado quando ele é concluído, recuperando os dados.
Casos de uso
Se suas operações não estão fazendo muito trabalho pesado, como consultar dados enormes do database, vá em frente com o modo síncrono, de outra forma assíncrona.
De maneira assíncrona, você pode mostrar um indicador de Progresso para o usuário, enquanto no fundo você pode continuar com seus trabalhos pesados. Este é um cenário ideal para aplicativos GUI.
Isso se tornaria um pouco mais claro se você adicionar uma linha aos dois exemplos:
var result = database.query("SELECT * FROM hugetable"); console.log(result.length); console.log("Hello World");
O segundo:
database.query("SELECT * FROM hugetable", function(rows) { var result = rows; console.log(result.length); }); console.log("Hello World");
Tente executá-los, e você notará que o primeiro exemplo (síncrono), o result.length, será impresso ANTES da linha “Hello World”. No segundo exemplo (asynchronous), o result.length será (muito provavelmente) impresso APÓS a linha “Hello World”.
Isso porque, no segundo exemplo, o database.query
é executado de forma assíncrona em segundo plano, e o script continua imediatamente com o “Hello World”. O console.log(result.length)
é executado apenas quando a consulta do database é concluída.
Primeiro, percebo que estou atrasado em responder a essa pergunta.
Antes de discutir síncrono e asynchronous, vamos examinar brevemente como os programas são executados.
No caso síncrono , cada instrução é concluída antes que a próxima instrução seja executada. Nesse caso, o programa é avaliado exatamente na ordem das instruções.
É assim que funciona asynchronous em JavaScript. Existem duas partes no mecanismo JavaScript, uma parte que examina as operações de código e enfileiramento e outra que processa a fila. O processamento da fila acontece em um thread, é por isso que apenas uma operação pode acontecer por vez.
Quando uma operação assíncrona (como a segunda consulta ao database) é vista, o código é analisado e a operação é colocada na fila, mas, nesse caso, um retorno de chamada é registrado para ser executado quando essa operação for concluída. A fila pode ter muitas operações já. A operação na frente da fila é processada e removida da fila. Depois que a operação da consulta do database for processada, a solicitação será enviada ao database e, quando concluída, o retorno de chamada será executado na conclusão. Neste momento, o processador de filas tendo “manipulado” a operação se move na próxima operação – neste caso
console.log("Hello World");
A consulta do database ainda está sendo processada, mas a operação console.log está na frente da fila e é processada. Esta sendo uma operação síncrona é executada imediatamente resultando imediatamente na saída “Hello World”. Algum tempo depois, a operação do database é concluída, somente então o retorno de chamada registrado com a consulta é chamado e processado, configurando o valor do resultado da variável em linhas.
É possível que uma operação assíncrona resulte em outra operação assíncrona, essa segunda operação será colocada na fila e, quando chegar à frente da fila, será processada. Chamar o retorno de chamada registrado com uma operação assíncrona é como o tempo de execução do JavaScript retorna o resultado da operação quando isso é feito.
Um método simples de saber qual operação JavaScript é assíncrona é observar se ele exige um retorno de chamada – o retorno de chamada é o código que será executado quando a primeira operação for concluída. Nos dois exemplos na questão, podemos ver apenas o segundo caso tem um retorno de chamada, por isso é a operação assíncrona dos dois. Nem sempre é o caso devido aos diferentes estilos de manipulação do resultado de uma operação assíncrona.
Para aprender mais, leia sobre promises. As promises são outra maneira pela qual o resultado de uma operação assíncrona pode ser manipulado. O bom das promises é que o estilo de codificação parece mais um código síncrono.
Muitas bibliotecas, como o nó ‘fs’, fornecem estilos síncronos e asynchronouss para algumas operações. Nos casos em que a operação não demora muito e não é muito usada – como no caso de ler um arquivo de configuração – a operação de estilo síncrono resultará em um código mais fácil de ler.
No caso síncrono, o comando console.log não é executado até que a consulta SQL tenha terminado a execução.
No caso asynchronous, o comando console.log será executado diretamente. O resultado da consulta, em seguida, será armazenado pela function “retorno de chamada” algum tempo depois.
A principal diferença é com a programação assíncrona, você não interrompe a execução de outra forma. Você pode continuar executando outro código enquanto o ‘pedido’ está sendo feito.
A function torna o segundo asynchronous.
O primeiro força o programa a esperar que cada linha termine de rodar antes que a próxima possa continuar. O segundo permite que cada linha seja executada em conjunto (e de forma independente) de uma só vez.
Idiomas e frameworks (js, node.js) que permitem asynchronous ou simultaneidade são ótimos para coisas que requerem transmissão em tempo real (por exemplo, bate-papo, aplicativos de estoque).
Programação de Sincronização
Linguagens de programação como C, C #, Java são programações de synchronization, o que sempre que você escreve será executado na ordem de sua escrita.
-GET DATA FROM SQL. //Suppose fetching data take 500 msec -PERFORM SOME OTHER FUNCTION. //Performing some function other will take 100 msec, but execution of other //task start only when fetching of sql data done (ie some other function //can execute only after first in process job finishes). -TOTAL TIME OF EXECUTION IS ALWAYS GREATER THAN (500 + 100 + processing time) msec
Assíncrono
O NodeJs vem com um recurso asynchronous, é de natureza não-bloqueante, suponha que em qualquer tarefa de E / S que esteja demorando (buscando, escrevendo, lendo), o nodejs não ficará ocioso e esperará que a tarefa seja finalizada. Começará a executar as próximas tarefas na fila e, sempre que essa tarefa de conclusão de tarefas for concluída, ela será notificada usando o retorno de chamada. O exemplo a seguir ajudará:
//Nodejs uses callback pattern to describe functions. //Please read callback pattern to understand this example //Suppose following function (I/O involved) took 500 msec function timeConsumingFunction(params, callback){ //GET DATA FROM SQL getDataFromSql(params, function(error, results){ if(error){ callback(error); } else{ callback(null, results); } }) } //Suppose following function is non-blocking and took 100 msec function someOtherTask(){ //some other task console.log('Some Task 1'); console.log('Some Task 2'); } console.log('Execution Start'); //Start With this function timeConsumingFunction(params, function(error, results){ if(error){ console.log('Error') } else{ console.log('Successfull'); } }) //As (suppose) timeConsumingFunction took 500 msec, //As NodeJs is non-blocking, rather than remain idle for 500 msec, it will start //execute following function immediately someOtherTask();
Em resumo, a saída é como:
Execution Start //Roughly after 105 msec (5 msec it'll take in processing) Some Task 1 Some Task 2 //Roughly After 510 msec Error/Successful //depends on success and failure of DB function execution
A diferença é clara onde a synchronization irá definitivamente levar mais de 600 (500 + 100 + tempo de processamento) mseg, async economiza tempo.