Rien n'est véritablement parallèle dans node.js depuis qu'il est mono-thread. Cependant, plusieurs événements peuvent être planifié et exécuté dans une séquence que vous ne pouvez pas déterminer à l'avance. Et certaines choses comme l'accès de base de données sont en fait des "parallèle" dans la base de données requêtes sont exécutées dans des threads séparés, mais sont ré-intégré dans le flux d'événements.
Alors, comment voulez-vous programmer un rappel sur plusieurs gestionnaires d'événements? Eh bien, c'est une technique courante utilisée dans les animations dans le navigateur javascript: utilisation d'une variable pour suivre la réalisation.
Cela sonne comme un hack et il est, et il semble potentiellement salissante, laissant un tas de variables globales autour de faire le suivi et, dans une moindre langue il serait. Mais en javascript, nous pouvons utiliser des bouchons:
function fork (async_calls, shared_callback) {
var counter = async_calls.length;
var callback = function () {
counter --;
if (counter == 0) {
shared_callback()
}
}
for (var i=0;i<async_calls.length;i++) {
async_calls[i](callback);
}
}
// usage:
fork([A,B,C],D);
Dans l'exemple ci-dessus, nous simplifier le code en supposant la async et les fonctions de rappel nécessitent pas d'arguments. Vous pouvez bien sûr modifier le code pour passer des arguments à la async fonctions et ont la fonction de rappel d'accumuler les résultats et le passer à la shared_callback fonction.
Réponse supplémentaire:
En fait, même comme il est, qu' fork()
fonction peut déjà passer des arguments à la async fonctions à l'aide d'une fermeture:
fork([
function(callback){ A(1,2,callback) },
function(callback){ B(1,callback) },
function(callback){ C(1,2,callback) }
],D);
la seule chose qui reste à faire est d'accumuler les résultats à partir de A,B,C et D.
Même plus de réponse:
Je ne pouvais pas résister. N'arrêtais pas de penser à ce sujet pendant le petit déjeuner. Voici une implémentation de l' fork()
qui accumule les résultats (généralement passés en argument à la fonction de rappel):
function fork (async_calls, shared_callback) {
var counter = async_calls.length;
var all_results = [];
function makeCallback (index) {
return function () {
counter --;
var results = [];
// we use the arguments object here because some callbacks
// in Node pass in multiple arguments as result.
for (var i=0;i<arguments.length;i++) {
results.push(arguments[i]);
}
all_results[index] = results;
if (counter == 0) {
shared_callback(all_results);
}
}
}
for (var i=0;i<async_calls.length;i++) {
async_calls[i](makeCallback(i));
}
}
C'était assez facile. Cela rend fork()
assez d'usage général et peut être utilisé pour synchroniser plusieurs non-homogène des événements.
Exemple d'utilisation dans Node.js:
// Read 3 files in parallel and process them together:
function A (c){ fs.readFile('file1',c) };
function B (c){ fs.readFile('file2',c) };
function C (c){ fs.readFile('file3',c) };
function D (result) {
file1data = result[0][1];
file2data = result[1][1];
file3data = result[2][1];
// process the files together here
}
fork([A,B,C],D);
Mise à jour
Ce code a été écrit avant l'existence de bibliothèques, comme async.js ou les différents promesse basée bibliothèques. J'aimerais croire que async.js a été inspiré par cela, mais je n'ai pas de preuve. De toute façon.. si vous envisagez de le faire aujourd'hui, jetez un oeil à async.js ou promesses. Il suffit de considérer la réponse ci-dessus une bonne explication/illustration de la façon dont les choses comme async.en parallèle, un travail.