2013-05-26 4 views
1

Lorsque je reçois un événement "on" côté serveur, je souhaite démarrer une tâche en parallèle afin de ne pas bloquer le thread de boucle d'événement en cours. Est-il possible de le faire? Comment?Comment exécuter une tâche asynchrone avec socket.io et node.js?

Je ne veux pas bloquer la boucle côté serveur et je veux être en mesure de renvoyer un message au client une fois la tâche terminée, quelque chose comme:

client.on('execute-parallel-task', function(msg) { 
    setTimeout(function() { 
     // do something that takes a while 
     client.emit('finished-that-task'); 
    },0); 
    // this block should return asap, not waiting for the previous call 
}); 

Je ne suis pas sûr si setTimeout fera le travail.

Répondre

1

Vous n'avez pas besoin de setTimeout. Votre fonction (msg) sera appelée une fois la tâche d'exécution parallèle terminée.

si vous concevez une tâche à exécuter de manière asynchrone, vous pouvez regarder quelque chose comme le async lib pour Node.js

Async Node JS Link

+0

Je peux utiliser async.parallel sans problèmes mais le serveur répondrait-il à d'autres demandes pendant que mon (faire quelque chose qui prend un peu de temps) est en cours d'exécution? va-t-il exécuter les deux codes en même temps? –

+0

oui, c'est comme ça que fonctionne async ... C'est fondamentalement un thread (vous n'avez pas de threads dans node.js) ... chaque fois qu'une partie attend que quelque chose se passe, un autre code s'exécute et quand quelque chose se passe, un évènement est appelé le gestionnaire de droite le gère .. http://stevehanov.ca/blog/index.php?id=127 –

+0

Si vous avez besoin d'un modèle de filetage, vous pourriez avoir choisi la technologie usée pour votre backend ... avoir plusieurs processus de communication entre eux n'est pas aussi efficace que les threads ... en fait vous créeriez des threads en utilisant des processus == beaucoup plus frais généraux avec beaucoup plus de complexité pour aucun paiement. –

2

Il dépend de ce que l'prend un certain temps est. S'il prend un certain temps de manière asynchrone (vous pouvez dire parce que vous devrez enregistrer un rappel ou gestionnaire complete), et prend un certain temps parce qu'il est bloqué sur quelque chose comme IO, plutôt que lié au processeur, il sera intrinsèquement parallèle.

Si cependant, est quelque chose lié synchrone ou CPU, alors que vous pouvez utiliser setTimeout, etc. setImmediate pour renvoyer un message immédiatement, une fois que le gestionnaire pour setTimeout ou setImmediate exécute, votre seul thread d'exécution sera bloqué la manipulation que; vous n'êtes pas vraiment la fixation le problème, simplement le report.

Pour afficher un comportement parallèle réel, vous devez lancer un child process. Vous pouvez utiliser la fonctionnalité de transmission de message pour informer votre opérateur du travail à effectuer et pour notifier le processus parent une fois le travail terminé.

var cp = require('child_process'); 
var child = cp.fork(__dirname + '/my-child-worker.js'); 

n.on('message', function(m) { 
    if (m === "done") { 
     // Whey! 
    } 
}); 

n.send(/* Job id, or something */); 

Puis dans my-child-worker.js;

process.on('message', function (m) { 
    switch (m) { 
     case 'get-x': 
      // blah 
     break; 
     // other jobs 
    } 

    process.send('done'); 
}); 
+0

le processus enfant semble parfait mais je devrais exécuter un processus bash, et je voulais juste exécuter une fonction javascript. le modèle en cours d'exécution de node.js est un thread unique, donc je ne peux exécuter que deux threads si je produis un nouveau processus? –

+0

Chaque processus enfant aura son propre thread, séparé du thread du processus parent. Cela vous donne une exécution parallèle. Est-ce que cela répond à votre question ... Je n'ai pas compris votre commentaire complètement! – Matt

+0

donc vous utilisez node.js pour créer des processus, en utilisant ipc pour simuler des threads dans node.js? ne serait-il pas préférable d'utiliser un serveur thread supporté à la place? –