web-dev-qa-db-fra.com

Comment puis-je exécuter un module node.js en tant que processus enfant d'un programme node.js?

Voici mon problème. J'ai implémenté un petit script qui fait des calculs lourds, en tant que module node.js. Donc, si je tape "node myModule.js", il calcule pendant une seconde, puis renvoie une valeur. Maintenant, je veux utiliser ce module de mon programme Node.JS principal. Je pourrais simplement mettre tout le calcul dans une fonction "doSomeCalculation" puis faire:

var myModule = require("./myModule");
myModule.doSomeCalculation();

Mais ce serait bloquant, donc ce serait mauvais. Je voudrais l'utiliser de manière non bloquante, comme les appels DB en mode natif, par exemple. J'ai donc essayé d'utiliser child_process.spawn et exec, comme ceci:

var spawn = require("child_process").spawn;
var ext = spawn("node ./myModule.js", function(err, stdout, stderr) { /* whatevs */ });
ext.on("exit", function() { console.log("calculation over!"); });

Mais, bien sûr, cela ne fonctionne pas. J'ai essayé d'utiliser un EventEmitter dans monModule, en émettant des événements "calculDone" et en essayant d'ajouter l'écouteur associé sur la variable "ext" dans l'exemple ci-dessus. Ça ne marche toujours pas.

Quant aux fourches, elles ne sont pas vraiment ce que j'essaie de faire. Forks nécessiterait de mettre le code lié au calcul dans le programme principal, de bifurquer, de calculer chez l'enfant pendant que le parent fait tout ce qu'il fait, puis comment pourrais-je retourner le résultat?

Voici donc ma question: puis-je utiliser un processus enfant pour effectuer un calcul non bloquant, lorsque le calcul est placé dans un fichier Node, ou est-ce simplement impossible? Dois-je faire le calcul lourd dans un script Python à la place? Dans les deux cas, comment puis-je passer des arguments au processus enfant - par exemple, une image?

49
user1822364

Je pense que ce que vous recherchez est l'API child_process.fork () .

Par exemple, si vous disposez des deux fichiers suivants:

Dans main.js:

var cp = require('child_process');
var child = cp.fork('./worker');

child.on('message', function(m) {
  // Receive results from child process
  console.log('received: ' + m);
});

// Send child process some work
child.send('Please up-case this string');

Dans worker.js:

process.on('message', function(m) {
  // Do work  (in this case just up-case the string
  m = m.toUpperCase();

  // Pass results back to parent process
  process.send(m.toUpperCase(m));
});

Ensuite, pour exécuter main (et générer un processus de travail enfant pour le code worker.js ...)

$ node --version
v0.8.3

$ node main.js 
received: PLEASE UP-CASE THIS STRING
128
broofa

Peu importe ce que vous utiliserez comme enfant (Node, Python, peu importe), Node ne s'en soucie pas. Assurez-vous simplement que votre script de calcul se termine après tout est fait et le résultat est écrit dans stdout.

La raison pour laquelle cela ne fonctionne pas est que vous utilisez spawn au lieu de exec .

3
Aleksei Zabrodskii