Qu'est-ce que les E / S non bloquantes ou asynchrones dans Node.js?

136

Dans le contexte des moteurs Javascript côté serveur, qu'est-ce que les E / S non bloquantes ou les E / S asynchrones? Je vois cela comme un avantage par rapport aux implémentations côté serveur Java.

Anand
la source
3
Il est utile de penser aux balises de script dans l'environnement du navigateur afin de comprendre ce concept. Zakas a un excellent article à ce sujet - les premières sections devraient suffire à expliquer le concept de blocage: nczonline.net/blog/2010/08/10/what-is-a-non-blocking-script
netpoetica

Réponses:

317

Synchrone vs asynchrone

L'exécution synchrone fait généralement référence au code s'exécutant en séquence. L'exécution asynchrone fait référence à une exécution qui ne s'exécute pas dans la séquence dans laquelle elle apparaît dans le code. Dans l'exemple suivant, l'opération synchrone déclenche les alertes en séquence. Dans l'opération asynchrone, alors que alert(2)semble s'exécuter en second, ce n'est pas le cas.

Synchrone: 1,2,3

alert(1);
alert(2);
alert(3);

Asynchrone: 1,3,2

alert(1);
setTimeout(() => alert(2), 0);
alert(3);

Blocage vs non blocage

Le blocage fait référence aux opérations qui bloquent la poursuite de l'exécution jusqu'à la fin de cette opération. Non bloquant fait référence au code qui ne bloque pas l'exécution. Dans l'exemple donné, localStorageest une opération de blocage car elle bloque l'exécution à lire. D'autre part, fetchest une opération non bloquante car elle ne stagne pas alert(3)de l'exécution.

// Blocking: 1,... 2
alert(1);
var value = localStorage.getItem('foo');
alert(2);

// Non-blocking: 1, 3,... 2
alert(1);
fetch('example.com').then(() => alert(2));
alert(3);

Avantages

L'un des avantages des opérations non bloquantes et asynchrones est que vous pouvez maximiser l'utilisation d'un seul processeur ainsi que de la mémoire.

Exemple de blocage synchrone

Un exemple d'opérations synchrones et bloquantes est la façon dont certains serveurs Web comme ceux de Java ou PHP traitent les demandes d'E / S ou de réseau. Si votre code lit à partir d'un fichier ou de la base de données, votre code "bloque" tout après son exécution. Pendant cette période, votre machine conserve la mémoire et le temps de traitement pour un thread qui ne fait rien .

Afin de répondre à d'autres demandes pendant que ce thread est bloqué, cela dépend de votre logiciel. La plupart des logiciels de serveur génèrent plus de threads pour répondre aux demandes supplémentaires. Cela nécessite plus de mémoire consommée et plus de traitement.

Exemple asynchrone et non bloquant

Les serveurs asynchrones et non bloquants - comme ceux créés dans Node - n'utilisent qu'un seul thread pour traiter toutes les demandes. Cela signifie qu'une instance de Node tire le meilleur parti d'un seul thread. Les créateurs l'ont conçu en partant du principe que les E / S et les opérations réseau sont le goulot d'étranglement.

Lorsque les demandes arrivent au serveur, elles sont traitées une par une. Cependant, lorsque le code desservi a besoin d'interroger la base de données par exemple, il envoie le rappel à une deuxième file d'attente et le thread principal continuera à fonctionner (il n'attend pas). Maintenant, lorsque l'opération de base de données se termine et revient, le rappel correspondant est retiré de la deuxième file d'attente et mis en file d'attente dans une troisième file d'attente où il est en attente d'exécution. Lorsque le moteur a une chance d'exécuter autre chose (comme lorsque la pile d'exécution est vidée), il récupère un rappel de la troisième file d'attente et l'exécute.

Joseph
la source
5
Je ne suis pas sûr de comprendre votre 2ème paragraphe sous Blocage en PHP . Êtes-vous en train de dire que "Bien que PHP se bloque normalement sur IO, ce n'est pas le cas parce que le système d'exploitation exécute automatiquement les opérations d'E / S."? Ou est-ce que vous dites que ce n'est pas un problème en PHP parce que PHP crée automatiquement un nouveau thread pour chaque requête afin qu'une requête bloquée n'interrompe pas tout l'environnement PHP? (Je suppose que ce dernier ..)
dcow
6
C'est ce dernier.
Joseph
2
attendez, si cela signifie ce dernier, quels sont les avantages des E / S PHP non bloquantes (comme reactPHP ou autre chose) par rapport au blocage. encore
confuse
5
@CharlieParker Oui. L'opération asynchrone s'exécute parallèlement à votre code. Mais le rappel qui "renvoie" aux résultats de l'opération asynchrone est mis en file d'attente pour exécution dans le code principal lorsque le code principal n'est pas occupé.
Joseph
2
@CharlieParker Voici un article qui traite plus des éléments internes du mécanisme asynchrone.
Joseph
7
var startTime = new Date().getTime();
var getEndTime = () => {
    var tempEndTime = new Date().getTime();
    var second = (tempEndTime - startTime)/1000
    return `took ${second} sec...to finish\n`
}

console.log('1: start App', getEndTime())
setTimeout(()=>{
    console.log('2: setTimeout', getEndTime())
}, 1000)
console.log('3: End App', getEndTime())

// console -> Process Order:  1 -> 3 -> 2

Exemple de code

Wayne Chiu
la source