我正在使用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
,或者它不是正确的工具?如果它不正确,我可以用什么来达到预期的效果?
或者我是否必须辞职才能进行深度嵌套的回调(未来的工作,我会这样做)并且必须通过将内联代码提取到命名函数中来缓解它?
答案 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
});
如果你需要使用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) {
});
希望这有帮助。