Comment NodeJS peut-il être «non bloquant»?

14

J'apprends NodeJS et je voulais juste clarifier quelque chose. Jusqu'à présent, dans plusieurs tutoriels et livres d'introduction, ils ont décrit l'architecture "non bloquante" de Node - ou plutôt qu'il est possible (et recommandé, l'intégralité du point) de coder de manière non bloquante.

Ainsi, par exemple, cet exemple a été donné dans un livre que je lis d'une manière asynchrone pour obtenir des données d'une base de données.

http.createServer(function (req, res) {
  database.getInformation(function (data) {
      res.writeHead(200);
      res.end(data);
  });
});

Ce qui se passe (si je comprends bien), c'est que Node fait l'appel à la base de données, puis continue de traiter ce qui peut être le prochain sur la pile d'appels. Lorsque la demande de base de données est terminée, la variable de données dans la fonction de rappel anonyme sera remplie et cette fonction ajoutée à la pile d'appels (et exécutée par la suite lorsque Node y accède).

Ma question est, qu'est - ce que le traitement de la demande de base de données? Node doit sûrement bloquer pendant qu'il fait ça? Qu'est-ce qui prend en charge la demande de base de données? Ou si Node attend une demande HTTP GET asynchrone vers une ressource externe, qu'est-ce qui prend en charge cette demande qui permet à Node de continuer à traiter la pile d'appels et d'être "non bloquant"?

Anonyme
la source

Réponses:

17

Lorsque Node.js est décrit comme "non bloquant", cela signifie spécifiquement que son entrée / sortie est non bloquante. Node utilise libuv pour gérer son E / S d'une manière indépendante de la plateforme. Sous Windows, il utilise des ports d'achèvement d'E / S, sous Unix, il utilise epoll / kqueue / select / etc. Ainsi, il fait une demande d'E / S non bloquante (qui peut avoir une surveillance de thread en arrière-plan, mais cela n'est jamais exposé à JavaScript) et sur un résultat, il la met en file d'attente dans la boucle d'événements qui appelle le rappel JavaScript sur le principal (lire: uniquement) fil JavaScript.

Pour les bases de données, cela dépend de la façon dont la bibliothèque est écrite. S'il utilise HTTP pour communiquer (comme le font certaines bases de données NoSQL), il pourrait être facilement écrit en JavaScript pur en utilisant la httpbibliothèque de nœuds standard . S'il le fait d'une autre manière, eh bien, c'est à la bibliothèque. Il pourrait être écrit en C / C ++ et utiliser des threads d'arrière-plan tant que cette abstraction n'est jamais exposée au JavaScript.

En ce qui concerne votre question sur le «traitement» de la demande de base de données, idéalement, tout ce qui doit être fait est d'envoyer un simple message à une bibliothèque (par exemple, une instruction SQL ou une autre requête ou une demande de connexion), et à ce stade, votre JavaScript continue de chugging. Lorsque la bibliothèque est prête à renvoyer un message, elle renvoie un message à la file d'attente d'événements du nœud qui exécute le rappel, permettant à cet extrait de code de s'exécuter.

ckknight
la source
Il y a le netpaquet quand http n'est pas disponible.
Florian Margaine
Des détails qui pourraient vous aider. Le nœud exploite le moteur V8 JS. L'une des meilleures fonctionnalités de V8 est la facilité de liaison des processus C / C ++ aux appels JS. Les fonctions JavaScript bloquent mais tout ce qu'une fonction fait est d'appeler quelque chose sous le capot qui ne bloque pas. Ensuite, une autre fonction JS répond lorsque ce processus est terminé. Les fonctions JS se bloquant les unes les autres signifient que vous n'aurez jamais deux choses à essayer de faire quelque chose comme planifier une écriture au même emplacement de fichier en même temps, c'est là que je suppose que les multi-threads doivent être gérés. Il est toujours clair quelle demande est venue en premier dans le but de mettre les choses en file d'attente.
Erik Reppen