使用async.waterfall

时间:2014-03-15 02:27:02

标签: javascript node.js asynchronous async.js

我正在使用node.js和异步包。

这是我的代码:

async.waterfall(
[
    function(callback) {
        var data = getSomeData();
        callback(null, data);
    },
    function(data, callback) {
        someFunctionThatNeedsData(data);
        callback(null, 'done');
    }
],
function(err, result) {
}
);

getSomeData有一个异步HTTP请求,可以从Web服务中获取一些数据。我想等到收到回复,然后返回该数据并将其传递给someFunctionThatNeedsData

我期望的是getSomeData - 包括其内部的回调 - 必须在继续调用someFunctionThatNeedsData之前完成。

问题在于,尽管在此使用了waterfall函数,data在到达someFunctionThatNeedsData时尚未定义。

此外,从console.log我可以看到getSomeData的结尾在getSomeData内部的回调开始之前就已到达。

我是否错误地使用waterfall,或者它不是正确的工具?如果它不正确,我可以用什么来达到预期的效果?

或者我是否必须辞职才能进行深度嵌套的回调(未来的工作,我会这样做)并且必须通过将内联代码提取到命名函数中来缓解它?

2 个答案:

答案 0 :(得分:1)

  

getSomeData()有一个异步的http请求,它从Web服务中获取一些数据。

这就是问题所在。执行流程已经继续回调并执行它。这是异步函数的工作方式!

您必须将回调传递给getSomeData,一旦HTTP请求完成,它就会调用它。所以是的:您可能需要嵌套回调。

答案 1 :(得分:0)

如果您有异步操作。您没有必要使用async.waterfall。你可以在承诺链样式中做到这一点。

getSomeData().then(function(data) 
{
    var changeData = changeYourData(data);
    return changeData;
}).then(function(changedData)
{
    // some more stuff with it. You can keep on forwarding to the next `then` 
}).catch(function(err)
{
    // if any error throw at any point will get catch here
}).finally(function() 
{
    // this one will guarantee get call no matter what,
    // exactly the same like async.waterfall end of chain callback
});

此示例适用于QWhen以及遵循标准的任何承诺库。

如果你需要使用async.waterfall(因为你可以使用Array.map驱动它) 您只需要在then

中回调即可
async.waterfall(
[
    function(callback) {
        // A 
        getSomeData().then(function(data)
        {
            callback(null, data);
        });
        // B - just throw the whole thing in
        callback(null , getSomeData());
    },
    function(data, callback) {
        // A
        someFunctionThatNeedsData(data);
        // B
        data.then(function(resolvedData)
        {
             someFunctionThatNeedsData(resolvedData);
             callback(null, 'done');
        });
    }
],
function(err, result) {
});

希望这有帮助。