web-dev-qa-db-fra.com

Qu'est-ce qu'une E / S asynchrone ou non bloquante dans Node.js?

Dans le contexte des moteurs Javascript côté serveur, qu'est-ce qu'une entrée/sortie non bloquante ou une entrée/sortie asynchrone? Je vois cela mentionné comme un avantage par rapport aux implémentations côté serveur Java).

123
Anand

Synchrone vs asynchrone

L'exécution synchrone fait généralement référence à un code qui s'exécute en séquence. L'exécution asynchrone fait référence à une exécution qui ne s'exécute pas dans l'ordre dans lequel elle apparaît dans le code. Dans l'exemple suivant, l'opération synchrone provoque le déclenchement séquentiel des alertes. En mode asynchrone, alors que alert(2) semble exécuter en deuxième lieu, ce n'est pas le cas.

Synchrone: 1,2,

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

Asynchrone: 1,3,2

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

Blocage vs non bloquant

Le blocage fait référence aux opérations qui bloquent toute exécution ultérieure 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é, localStorage est une opération bloquante car elle empêche l'exécution de lire. D'autre part, fetch est une opération non bloquante car elle ne bloque pas l'exécution de alert(3).

// 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 asynchrones non bloquantes est que vous pouvez optimiser l'utilisation d'un seul processeur ainsi que de la mémoire.

Synchrone, exemple bloquant

Un exemple d’opération de blocage synchrone est la manière dont certains serveurs Web ressemblent à ceux de Java ou PHP handle IO ou requêtes réseau) Si votre code lit dans un fichier ou la base de données, votre code "bloque" tout son exécution après cette période. Au cours de cette période, votre ordinateur conserve la mémoire et le temps de traitement d'un thread qui n'est pas ne fais rien .

Afin de répondre aux autres demandes alors que ce fil 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 et plus de traitement.

Asynchrone, exemple non bloquant

Les serveurs asynchrones, 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 Les créateurs l’ont conçu en partant du principe que les opérations d’E/S et de réseau constituent le goulot d’étranglement.

Lorsque les demandes arrivent sur le serveur, elles sont traitées une par une. Cependant, lorsque le code desservi doit interroger la base de données par exemple, il envoie le rappel à une seconde file d'attente et le thread principal continue de s'exécuter (il ne attendez pas. Désormais, lorsque l'opération de base de données est terminée et renvoyée, le rappel correspondant est extrait 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 la possibilité d'exécuter autre chose (par exemple, 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.

295
Joseph
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

Code example

5
Wayne Chiu