Quelle est la différence entre la programmation synchrone et asynchrone (dans node.js)

J'ai lu nodebeginner et j'ai rencontré 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"); 

Je reçois ce qu'ils sont censés faire, ils interroge la base de données pour récupérer la réponse à la requête. Et puis console.log('Hello world') .

Le premier est censé être un code synchrone. Et le second est un code asynchrone.

La différence entre les deux pièces est très vague pour moi. Quelle serait la production?

Le programme Google sur la programmation asynchrone ne m'a pas aidé non plus.

    La différence est que dans le premier exemple , le programme va bloquer en première ligne. La ligne suivante ( console.log ) devra attendre.

    Dans le deuxième exemple , la console.log sera exécutée pendant que la requête est en cours de traitement. C'est-à-dire que la requête sera traitée en arrière-plan, alors que votre programme fait d'autres choses, et une fois que les données de la requête sont prêtes, vous ferez ce que vous voulez.

    Donc, en un mot: le premier exemple sera bloqué, tandis que le second ne le sera 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:

    1. Query finished
      Next line
    2. Next line
      Query finished

    Remarque
    Alors que Node lui-même est un seul thread , il existe une tâche qui peut être exécutée 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 de système de fichiers, tandis que le thread Node principal continue d'exécuter votre code javascript. Dans un serveur piloté par un événement comme Node, le thread du système de fichiers notifie le thread de Nœud principal de 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 principal du noeud décide ce qu'il faut faire avec ces données.

    Vous pouvez en savoir plus à ce sujet ici: comment fonctionne le modèle IO non bloqué à un seul thread dans Node.js

    La différence entre ces deux approches est la suivante:

    Mode synchrone: il attend que chaque opération soit terminée, puisqu'elle exécute la prochaine opération. Pour votre requête: La commande console.log() ne sera exécutée qu'à moins que la requête n'ait été exécutée pour obtenir tous les résultats de la base de données.

    Asynchrone: il n'attend jamais que chaque opération se termine, mais elle 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 commande console.log() sera exécutée peu de temps après la méthode Database.Query() . Alors que la requête Base de données s'exécute en arrière-plan et qu'elle charge le résultat une fois qu'il a fini de récupérer les données.

    Cas d'utilisation

    1. Si vos opérations ne font pas de levage très lourd, comme pour interroger d'énormes données de DB, passez en mode Synchrone autrement Asynchrone.

    2. De manière asynchrone, vous pouvez afficher un indicateur de Progrès à l'utilisateur en arrière-plan, vous pouvez continuer votre travail lourd. C'est un scénario idéal pour les applications GUI.

    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), la longueur du résultat sera imprimé avant la ligne 'Hello World'. Dans le deuxième exemple (asynchrone), la longueur du résultat sera (très probablement) imprimée APRÈS la ligne "Bonjour Monde".

    C'est parce que dans le deuxième exemple, la database.query est exécutée de manière asynchrone en arrière-plan, et le script continue tout de suite avec le «Bonjour Monde». La console.log(result.length) n'est exécutée que lorsque la requête de base de données est terminée.

    Tout d'abord, je me rends compte que je suis en retard pour répondre à cette question.

    Avant de discuter de synchrone et asynchrone, voyons brièvement comment les programmes fonctionnent.

    Dans le cas synchrone , chaque instruction est terminée avant que l'instruction suivante ne soit exécutée. Dans ce cas, le programme est évalué exactement dans l'ordre des énoncés.

    C'est ainsi que fonctionne Asynchronous en JavaScript. Il existe deux parties dans le moteur de JavaScript, une partie qui examine le code et les opérations d'enchaînement 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 mise en file d'attente, mais dans ce cas, un rappel est enregistré pour être exécuté lorsque cette opération est terminée. La file d'attente peut déjà avoir de nombreuses opérations. L'opération à l'avant de la file est traitée et supprimée de la file d'attente. Une fois que l'opération pour la requête de base de données est traitée, la demande est envoyée à la base de données et, une fois terminée, le rappel sera exécuté à la fin. À ce moment, le processeur de file d'attente ayant "manipulé" l'opération se déplace sur l'opération suivante – dans ce cas

      console.log("Hello World"); 

    La requête de base de données est en cours de traitement, mais l'opération console.log se trouve en face de la file d'attente et est traitée. Une opération synchrone est exécutée immédiatement résultant immédiatement dans la sortie "Hello World". Quelque temps plus tard, l'opération de base de données est terminée, alors le callback enregistré avec la requête est appelé et traité, en définissant la valeur du résultat de la variable sur les lignes.

    Il est possible qu'une opération asynchrone entraîne une autre opération asynchrone, cette deuxième opération sera mise en file d'attente et, en ce qui concerne l'avant de la file d'attente, elle sera traitée. L'appel du rappel enregistré avec une opération asynchrone est la façon dont le temps d'exécution de JavaScript renvoie le résultat de l'opération lorsqu'il est terminé.

    Une méthode simple pour savoir quelle opération JavaScript est asynchrone est de noter si elle nécessite un rappel – le rappel est le code qui sera exécuté lorsque la première opération sera terminée. Dans les deux exemples de la question, nous ne pouvons voir que le deuxième cas a un rappel, donc c'est l'opération asynchrone des deux. Ce n'est pas toujours le cas en raison des différents styles de traitement du résultat d'une opération asynchrone.

    Pour en savoir plus, lisez les promesses. Les promesses sont une autre façon de traiter le résultat d'une opération asynchrone. La bonne chose à propos des promesses est que le style de codage se ressemble plus au code synchrone.

    Beaucoup de bibliothèques comme 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 utilisée beaucoup – comme dans le cas de la lecture d'un fichier de configuration – l'opération de style synchrone entraînera un code plus facile à lire.

    Dans le cas synchrone, la commande console.log n'est pas exécutée tant que la requête SQL n'a pas été exécutée.

    Dans le cas asynchrone, la commande console.log sera directement exécutée. Le résultat de la requête sera ensuite stocké par la fonction "callback" quelque temps après.

    La différence principale est 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 fonction rend la seconde asynchrone.

    Le premier force le programme à attendre que chaque ligne se termine avant que la prochaine ne puisse se poursuivre. Le second permet à chaque ligne de s'exécuter ensemble (et indépendamment) à la fois.

    Les langues et les frameworks (js, node.js) qui permettent une synchronisation asynchrone ou concurrente sont parfaits pour les choses nécessitant une transmission en temps réel (p. Ex. Chat, applications stock).