node.js async.series 是它应该如何工作的?

Posted

技术标签:

【中文标题】node.js async.series 是它应该如何工作的?【英文标题】:node.js async.series is that how it is supposed to work? 【发布时间】:2013-04-04 20:18:46 【问题描述】:
var async = require('async');

function callbackhandler(err, results) 
    console.log('It came back with this ' + results);
   

function takes5Seconds(callback) 
    console.log('Starting 5 second task');
    setTimeout( function()  
        console.log('Just finshed 5 seconds');
        callback(null, 'five');
    , 5000);
   

function takes2Seconds(callback) 
    console.log('Starting 2 second task');
    setTimeout( function()  
        console.log('Just finshed 2 seconds');
        callback(null, 'two');
    , 2000); 
   

async.series([takes2Seconds(callbackhandler), 
              takes5Seconds(callbackhandler)], function(err, results)
    console.log('Result of the whole run is ' + results);
) 

输出如下所示:

Starting 2 second task
Starting 5 second task
Just finshed 2 seconds
It came back with this two
Just finshed 5 seconds
It came back with this five

我期待takes2Second 函数在takes5Second 开始之前完全完成。 这就是它应该如何工作的方式。请告诉我。 最后的功能永远不会运行。谢谢。

【问题讨论】:

【参考方案1】:

不完全是。您正在立即执行这些函数(一旦对数组求值),这就是它们似乎同时开始的原因。

传递给每个要执行的函数的回调是异步库内部的。一旦你的函数完成,你就执行它,传递一个错误和/或一个值。您不需要自己定义该函数。

最后一个函数永远不会在您的情况下运行,因为异步需要您调用以继续执行该系列中的下一个函数的回调函数实际上从未被执行(只有您的 callbackHandler 函数被执行)。

试试这个:

async.series([
    takes2Seconds,
    takes5seconds
], function (err, results) 
    // Here, results is an array of the value from each function
    console.log(results); // outputs: ['two', 'five']
);

【讨论】:

James,感谢您对正在发生的事情的清晰解释。在我按照建议进行这些更改后它可以工作。是否可以将参数传递给这些函数? 在进一步阅读文档时,看起来我应该使用 async.apply 将参数传递给函数。【参考方案2】:

James 为您详细介绍了async.series。请注意,您可以在系列数组中设置匿名函数,然后使用参数调用您的实际函数

var async = require('async')
var param1 = 'foobar'
function withParams(param1, callback) 
  console.log('withParams function called')
  console.log(param1)
  callback()

function withoutParams(callback) 
  console.log('withoutParams function called')
  callback()

async.series([
  function(callback) 
    withParams(param1, callback)
  ,
  withoutParams
], function(err) 
  console.log('all functions complete')
)

【讨论】:

诺亚,是的,我最终想通了。无论如何,感谢您发布它。【参考方案3】:

我首选的创建异步系列的方法是使用操作数组,如下所示;

var async = require('async'),
    operations = [];

operations.push(takes2Seconds);
operations.push(takes5seconds);

async.series(operations, function (err, results) 
    // results[1]
    // results[2]
);

function takes2Seconds(callback) 
    callback(null, results);


function takes5seconds(callback) 
    callback(null, results);

【讨论】:

有趣的是,您如何将 .series() 函数放在前面。我有点喜欢。 async.series如何知道其中一个操作遇到了错误?【参考方案4】:
async.series
    ([  
        function (callback)
        
            response=wsCall.post(user,url,method,response);
            console.log("one");
            callback();
        
        ,
        function (callback)
        
            console.log("two");
            //console.log(response);
            callback();
        
    ]
    ,
    function(err) 
    
        console.log('Both a and b are saved now');
        console.log(response);
    );

【讨论】:

欢迎来到 SO,感谢您的回答。如果它的格式正确并解释一下,这个答案会更有用。并不是说您的帮助不受欢迎,但就目前而言,您的答案可能会因其质量问题而被删除,这对您或社区中的任何其他人都没有好处。【参考方案5】:

async.series 中,所有函数都是串行执行的,每个函数的合并输出都会传递给最终的回调。例如

var async = require('async');
async.series([
    function (callback) 
        console.log('First Execute..');
        callback(null, 'userPersonalData');
    ,
    function (callback) 
        console.log('Second Execute.. ');
        callback(null, 'userDependentData');
    
],
function (err, result) 
    console.log(result);
);

输出:

First Execute..
Second Execute..
['userPersonalData','userDependentData'] //result

【讨论】:

如何执行这个异步系列?

以上是关于node.js async.series 是它应该如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

node.js async.series 不工作

Node.js中流程控制

Node.js异步库async

node.js async.js nextTick vs setImmediate

node.js async.js nextTick vs setImmediate

使用 Node.js、Async 和 Formidable 处理错误