节点模块中的并行流

时间:2013-07-14 18:17:54

标签: node.js asynchronous express node-async

我正在使用快递应用。我希望为我想要运行的一系列函数提供并行流。我正在考虑使用async模块。

我想知道是否还有其他模块比这更好?

其次我想知道这些函数是否必须是异步的?假设我有这样的代码

var sum = function(x, y){
   return (x + y)
}

async.parallel([
    function(callback){
        setTimeout(function(){
            result = sum (x, y); //just an example for a synchronous function
            callback(null, result);
        }, 100);
    },
    function(callback){
        result = sum (x, y); //just an example for a synchronous function
        callback(null, result);
    }

],
// optional callback
function(err, results){
    console.log(result);
    // the results array will equal ['one','two'] even though
    // the second function had a shorter timeout.
});

所以你可以在里面找到同步的功能。那么这两个还是会并行运行吗?

我还听说在node.js中,只有I / O任务可以并行运行,因为node.js是单线程的。这是真的吗?所以如果我没有在异步模块中的I / O任务,它们也不会并行运行而只是出现?

请帮忙。

3 个答案:

答案 0 :(得分:2)

Node.js 单线程和(开箱即用)单核

因此,Node.js中没有真正并行,因为它是单线程的。

只有当您的任务包含异步代码时,async.parallel方法才有用:它将等待所有响应,然后执行回调中的代码。 ,如果您的任务仅包含同步代码,则结果将是同步的。

所以你最后一个问题的答案是

如果您想尝试其他控制流模块,请尝试Q。它实现了Javascript Promises,使异步代码更易于阅读和组织。

如果您想真正并行化您的任务,请查看child processcluster module

还有一些特殊的本机模块Threads à gogo实现了线程化。


代码的完整示例:

var async = require('async');

sum = function(x, y) {
  return (x + y)
}

x = 2;
y = 3;

async.parallel([
    function(callback) {
      setTimeout(function() {
        result = sum(x, y);
        console.log('f1');
        callback(null, result);
      }, 100);
    },
    function(callback) {
      result = sum(x, y);
      console.log('f2');
      callback(null, result);
    }

  ],

  function(err, results) {
    console.log(result);
  }
);

如果运行这段代码,输出结果将始终为:f2, f1, 5。这是因为第一个函数中有setTimeout,但执行代码的方式是同步

如果您想要被说服,请在第一个函数中删除setTimeout,并看到输出始终f1, f2, 5

所以:

  • async.parallel非常有用,如果你想同时运行两个HTTP请求(它们是异步的),并等待它们都完成。

  • 如果在其中放入同步代码,则async.parallel没有用,因为代码将以同步方式执行。

答案 1 :(得分:1)

async是这类任务的事实上的模块,请继续使用。

不,这些功能不是必须异步的。我相信你的所有问题都可以通过以下方式回答:http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/,其中以下是重点:

  

Node.js为您的代码保留一个线程,然而一切都在运行   并行,除了你的代码。

答案 2 :(得分:0)

另一种方法是使用promise(bluebird)。 请参阅此处的文档和示例用法http://bluebirdjs.com/docs/getting-started.html)。

如,

function f1() {... }
function f2() {... }
function f3() {... }

Promise.all[f1(), f2(), f3()] // run all functions parallel
  .then(() => { /*do something*/})
  .catch(err => { /*handle error*/ })