J'ai lu nodebeginner Et je suis tombé sur les deux morceaux de code suivants.
Le premier:
var result = database.query("SELECT * FROM hugetable");
console.log("Hello World");
Le deuxième:
database.query("SELECT * FROM hugetable", function(rows) {
var result = rows;
});
console.log("Hello World");
J'obtiens ce qu'ils sont censés faire, ils interrogent la base de données pour récupérer la réponse à la requête. Et puis console.log('Hello world')
.
Le premier est un code supposé synchrone. Et le second est le code asynchrone.
La différence entre les deux pièces est très vague pour moi. Quelle serait la sortie?
Googler sur la programmation asynchrone ne m'a pas non plus aidé.
database.query()
, je devrais l'appeler de manière synchrone, non? ou quelle devrait être l'approche? (Cette question que j'ai depuis longtemps)Réponses:
La différence est que dans le premier exemple , le programme se bloque sur la première ligne. La ligne suivante (
console.log
) devra attendre.Dans le deuxième exemple , le
console.log
sera exécuté pendant que la requête est en cours de traitement. Autrement dit, la requête sera traitée en arrière-plan, pendant que votre programme fait autre chose, et une fois que les données de la requête sont prêtes, vous en ferez ce que vous voulez.Donc, en un mot: le premier exemple bloquera, tandis que le second ne le fera pas.
La sortie des deux exemples suivants:
// 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");
Serait:
Query finished
Next line
Next line
Query finished
Remarque
Bien que Node lui-même soit à thread unique , certaines tâches peuvent s'exécuter en parallèle. Par exemple, les opérations du système de fichiers se produisent dans un processus différent.
C'est pourquoi Node peut effectuer des opérations asynchrones: un thread effectue des opérations sur le système de fichiers, tandis que le thread principal de Node continue d'exécuter votre code javascript. Dans un serveur événementiel tel que Node, le thread du système de fichiers notifie au thread principal du nœud certains événements tels que l'achèvement, l'échec ou la progression, ainsi que toutes les données associées à cet événement (comme le résultat d'une requête de base de données ou d'une erreur message) et le thread Node principal décide quoi faire avec ces données.
Vous pouvez en savoir plus à ce sujet ici: Fonctionnement du modèle d'E / S non bloquant à thread unique dans Node.js
la source
request query.; 5 seconds later when the request is done; console.log
:; lorsque le second on exécute:request query; console.log; work on the query
;database.query
termine si vite qu'au moment où nous atteignonsconsole.log
la tâche est déjà terminée.console.log("Next line");
dans l'exemple 2 était à l'intérieur de la fonction anonyme, donc juste aprèsconsole.log("query finished");
, cela signifierait que "Next Line" serait imprimé APRÈS "la requête terminée" n'est-ce pas? Donc, si j'ai tout de manière imbriquée, tout fonctionnerait de manière synchrone, donc je n'aurais pas à m'inquiéter d'utiliser des versions synchrones de certaines fonctions. Ai-je raison dans ma compréhension?La différence entre ces deux approches est la suivante:
De manière synchrone: il attend que chaque opération se termine, après cela seulement il exécute l'opération suivante. Pour votre requête: la
console.log()
commande ne sera pas exécutée tant que & à moins que la requête ne soit terminée pour obtenir tout le résultat de la base de données.De manière asynchrone: il n'attend jamais la fin de chaque opération, mais exécute toutes les opérations dans le premier GO uniquement. Le résultat de chaque opération sera traité une fois le résultat disponible. Pour votre requête: La
console.log()
commande sera exécutée peu de temps après laDatabase.Query()
méthode. Pendant que la requête de base de données s'exécute en arrière-plan et charge le résultat une fois la récupération des données terminée.Cas d'utilisation
Si vos opérations ne font pas de gros travaux comme l'interrogation d'énormes données à partir de la base de données, continuez avec la manière synchrone sinon la manière asynchrone.
De manière asynchrone, vous pouvez montrer un indicateur de progression à l'utilisateur tandis qu'en arrière-plan, vous pouvez continuer vos travaux lourds. C'est un scénario idéal pour les applications GUI.
la source
console.log
?Cela deviendrait un peu plus clair si vous ajoutez une ligne aux deux exemples:
var result = database.query("SELECT * FROM hugetable"); console.log(result.length); console.log("Hello World");
Le deuxième:
database.query("SELECT * FROM hugetable", function(rows) { var result = rows; console.log(result.length); }); console.log("Hello World");
Essayez de les exécuter et vous remarquerez que le premier exemple (synchrone), result.length, sera imprimé AVANT la ligne «Hello World». Dans le deuxième exemple (asynchrone), le result.length sera (très probablement) imprimé APRÈS la ligne "Hello World".
C'est parce que dans le deuxième exemple, le
database.query
est exécuté de manière asynchrone en arrière-plan, et le script continue tout de suite avec le "Hello World". Leconsole.log(result.length)
n'est exécuté que lorsque la requête de base de données est terminée.la source
Premièrement, je me rends compte que je suis en retard pour répondre à cette question.
Avant de parler de synchrone et asynchrone, examinons brièvement le fonctionnement des programmes.
Dans le cas synchrone , chaque instruction se termine avant l'exécution de l'instruction suivante. Dans ce cas, le programme est évalué exactement dans l'ordre des instructions.
C'est ainsi que fonctionne l' asynchrone en JavaScript. Le moteur JavaScript comprend deux parties, une partie qui examine le code et met en file d'attente les opérations et une autre qui traite la file d'attente. Le traitement de la file d'attente se produit dans un thread, c'est pourquoi une seule opération peut se produire à la fois.
Lorsqu'une opération asynchrone (comme la deuxième requête de base de données) est vue, le code est analysé et l'opération est placée dans la file d'attente, mais dans ce cas, un rappel est enregistré pour être exécuté lorsque cette opération se termine. La file d'attente peut déjà contenir de nombreuses opérations. L'opération au début de la file d'attente est traitée et supprimée de la file d'attente. Une fois l'opération pour la requête de base de données traitée, la demande est envoyée à la base de données et une fois terminée, le rappel sera exécuté à la fin. A ce moment, le processeur de file d'attente ayant "traité" l'opération passe à l'opération suivante - dans ce cas
console.log("Hello World");
La requête de base de données est toujours en cours de traitement, mais l'opération console.log est au début de la file d'attente et est traitée. Ceci étant une opération synchrone est exécutée immédiatement résultant immédiatement en la sortie «Hello World». Quelque temps plus tard, l'opération de base de données se termine, alors seulement le rappel enregistré avec la requête est appelé et traité, en définissant la valeur de la variable result en lignes.
Il est possible qu'une opération asynchrone aboutisse à une autre opération asynchrone, cette seconde opération sera mise dans la file d'attente et lorsqu'elle arrivera au début de la file d'attente, elle sera traitée. L'appel du rappel enregistré avec une opération asynchrone permet à l'exécution de JavaScript de renvoyer le résultat de l'opération lorsqu'elle est terminée.
Une méthode simple pour savoir quelle opération JavaScript est asynchrone consiste à noter si elle nécessite un rappel - le rappel est le code qui sera exécuté lorsque la première opération est terminée. Dans les deux exemples de la question, nous pouvons voir que seul le deuxième cas a un rappel, il s'agit donc de l'opération asynchrone des deux. Ce n'est pas toujours le cas en raison des différents styles de gestion du résultat d'une opération asynchrone.
Pour en savoir plus, lisez les promesses. Les promesses sont une autre façon de gérer le résultat d'une opération asynchrone. La bonne chose à propos des promesses est que le style de codage ressemble plus à du code synchrone.
De nombreuses bibliothèques telles que node 'fs' fournissent des styles synchrones et asynchrones pour certaines opérations. Dans les cas où l'opération ne prend pas longtemps et n'est pas beaucoup utilisée - comme dans le cas de la lecture d'un fichier de configuration - l'opération de style synchrone aboutira à un code plus facile à lire.
la source
Dans le cas synchrone, la commande console.log n'est pas exécutée tant que la requête SQL n'est pas terminée.
Dans le cas asynchrone, la commande console.log sera exécutée directement. Le résultat de la requête sera ensuite stocké par la fonction "callback" quelque temps après.
la source
La principale différence est qu'avec la programmation asynchrone, vous n'arrêtez pas l'exécution autrement. Vous pouvez continuer à exécuter un autre code pendant que la «demande» est en cours.
la source
La fonction rend le second asynchrone.
Le premier force le programme à attendre que chaque ligne se termine avant que la suivante puisse continuer. Le second permet à chaque ligne de fonctionner ensemble (et indépendamment) à la fois.
Les langages et les frameworks (js, node.js) qui autorisent l'asynchrone ou la concurrence sont parfaits pour les choses qui nécessitent une transmission en temps réel (par exemple, le chat, les applications stock).
la source
Les fonctions synchrones bloquent tandis que les fonctions asynchrones ne le sont pas. Dans les fonctions synchrones, les instructions se terminent avant l'exécution de l'instruction suivante. Dans ce cas, le programme est évalué exactement dans l'ordre des instructions et l'exécution du programme est interrompue si l'une des instructions prend un temps très long.
Les fonctions asynchrones acceptent généralement un rappel en tant que paramètre et l'exécution se poursuit sur la ligne suivante immédiatement après l'appel de la fonction asynchrone. Le rappel n'est appelé que lorsque l'opération asynchrone est terminée et que la pile d'appels est vide. Les opérations lourdes telles que le chargement de données à partir d'un serveur Web ou l'interrogation d'une base de données doivent être effectuées de manière asynchrone afin que le thread principal puisse continuer à exécuter d'autres opérations au lieu de bloquer jusqu'à la fin de cette longue opération (dans le cas des navigateurs, l'interface utilisateur se fige) .
Orginal Publié sur Github: Lien
la source
Programmation asynchrone dans JS:
Synchrone
Asynchrone
Exemple:
// This function is synchronous function log(arg) { console.log(arg) } log(1); // This function is asynchronous setTimeout(() => { console.log(2) }, 0); log(3)
la source
Programmation de synchronisation
Les langages de programmation comme C, C #, Java sont de la programmation de synchronisation, tout ce que vous écrivez sera exécuté dans l'ordre de votre écriture.
-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 (i.e 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
Async
NodeJs propose une fonction asynchrone, il est de nature non bloquante, supposons que dans toute tâche d'E / S qui prend du temps (récupération, écriture, lecture), nodejs ne restera pas inactif et attendra que la tâche soit terminée, c'est ll commence à exécuter les tâches suivantes dans la file d'attente, et chaque fois que cette tâche prend du temps, elle en informe à l'aide de la fonction de rappel. L'exemple suivant aidera:
//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();
En bref, la sortie est comme:
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
La différence est claire là où la synchronisation prendra certainement plus de 600 (500 + 100 + temps de traitement) msec, l'async fait gagner du temps.
la source