简体   繁体   English

使用异步瀑布

[英]Using async.waterfall

I'm using node.js and the async package. 我正在使用node.js和异步包。

Here's the code I have: 这是我的代码:

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

getSomeData has an asynchronous HTTP request that grabs some data from a web service. getSomeData有一个异步HTTP请求,该请求从Web服务获取一些数据。 I'd like to wait until I get a response, and then return that data and pass it to someFunctionThatNeedsData . 我想等到收到响应后,再返回该数据并将其传递给someFunctionThatNeedsData

What I expected was that getSomeData -- including the callback inside of it -- would have to complete before moving on to invoke someFunctionThatNeedsData . 我期望的是getSomeData (包括其中的回调)必须在继续调用someFunctionThatNeedsData之前完成。

The problem is that, despite using the waterfall function here, data is undefined by the time it gets to someFunctionThatNeedsData . 问题是,尽管在此处使用了waterfall函数,但data到达someFunctionThatNeedsData的时间someFunctionThatNeedsData

Additionally, from console.log I can see that the end of getSomeData is reached before the callback inside of getSomeData even begins. 此外,从console.log我可以看到,结束getSomeData达到内部的回调之前getSomeData甚至开始。

Am I using waterfall incorrectly, or is it just not the right tool here? 我使用了不正确的waterfall ,还是这里的工具不正确? If it's just not right, what can I use to achieve the desired effect? 如果不正确,我可以使用什么来达到预期的效果?

Or do I have to resign to having deeply nested callbacks (which, with future work, I will) and have to just mitigate it by extracting inline code into named functions? 还是我必须辞职于具有深度嵌套的回调(我将在以后的工作中使用它),并且必须通过将内联代码提取到命名函数中来减轻它的负担?

getSomeData() has an asynchronous http request that grabs some data from a web service. getSomeData()有一个异步http请求,该请求从Web服务获取一些数据。

This is the issue. 这就是问题。 The execution flow already continued to the callback and executed it. 执行流程已经继续到回调并执行了。 This is how asynchronous functions work! 这就是异步函数的工作方式!

You have to pass the callback to getSomeData , which calls it once the HTTP request finished. 您必须将回调传递给getSomeData ,一旦HTTP请求完成,该回调将getSomeData进行调用。 So yes: You may need to nest the callbacks. 是的:您可能需要嵌套回调。

If you have async operation. 如果您有异步操作。 You don't necessary to use async.waterfall. 您无需使用async.waterfall。 You could just do that in a promise chain style. 您可以按照承诺链样式进行操作。

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
});

This example will work with Q , When , and any promise lib that follow standard. 此示例将与QWhen和符合标准的任何promise lib一起使用。

If you need to use async.waterfall (because you could drive it with an Array.map) You just need to callback in your then 如果您需要使用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) {
});

Hope this help. 希望能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM