【问题标题】:Parallel Flow in Node Modules节点模块中的并行流
【发布时间】:2013-07-12 14:38:13
【问题描述】:

我有一个快速应用程序。我想为要运行的一组函数提供并行流。我正在考虑使用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 任务,它们也不会并行运行,而只是出现?

请帮忙。

【问题讨论】:

    标签: node.js asynchronous express node-async


    【解决方案1】:

    async 是这类任务的实际模块,随它去吧。

    不,这些函数不是必须是异步的。我相信你所有的问题都可以用这个来回答:http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/,以下是重点:

    Node.js 为您的代码保留一个线程,但是,一切都运行 除您的代码外,并行处理。

    【讨论】:

    • 您确定它们不需要同步吗?其次,非 I/O 是否也可以并行工作或像这样工作。正如许多人告诉我的那样,由于 node.js 在单线程中运行是不可能的,并且要实现它必须产生子进程。那么异步是否使用相同的子进程?
    • async.parallel 的回调函数将在两个函数都完成它们的工作时(即当它们调用它们的回调时)被调用,这与所涉及的函数的性质无关。不,异步不会产生进程来实现这一点,请阅读链接和async.parallel 以获得准确的想法。
    • 是的,我都经历过,但找不到关于 async.parallel 如何实现这一点的答案?所以很想知道它是如何做到的?
    • 它使用计数器来实现功能。 github.com/caolan/async/blob/master/lib/async.js#L101-L122
    • 你确定同步函数也可以运行吗?
    【解决方案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

    所以:

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

    • async.parallel 里面放同步代码就没用了,因为代码会以同步的方式执行。

    【讨论】:

    • 我已经列出了我将在问题中运行的代码类型。看看它,让我知道它们是否可以在并行模式下运行。在我看来,它们是异步的,但内部具有同步功能。所以请回答这些是否可以并行运行。
    【解决方案3】:

    另一种方法是使用 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*/ })
    

    【讨论】:

      猜你喜欢
      • 2014-06-23
      • 1970-01-01
      • 2014-04-30
      • 2016-12-10
      • 2018-02-16
      • 2016-02-24
      • 2017-11-10
      • 1970-01-01
      • 2019-12-19
      相关资源
      最近更新 更多