我撞到了另一个砖墙,在那里我无法完全掌握这里要做什么,或者至少如何以正确的方式去做。我已经实现了异步调用,因此我可以在瀑布方法中运行多个请求,每个请求都依赖于另一个请求的结果。这很好用,麻烦的是,瀑布中的第三步实际上需要发出多个请求。
我现在所拥有的内容如下:
async.waterfall([
function(callback) {
Object.find().exec(function (err, records) {
callback(null, records);
});
},
function(arg1, callback) {
request('url' + arg1.property + '', function(err, resp, body) {
callback(null, arg1, JSON.parse(body));
});
},
function(arg1, arg2, callback) {
var array = {newarray:[]};
arg2.forEach(function(eachField){
request('url' + arg2.property, function(err, resp, body) {
array.newarray.push(JSON.parse(body));
});
});
// AT THIS POINT THIS ARRAY SHOWS AS EMPTY
console.log(array);
callback(null, arg1, arg2, array);
}
], function (err, result) {
// RESULT BREAKS DUE TO FORMAT OF DIFFERENT RESPONSES
console.log(result);
});
这很有效。它发出第一个请求,将数据发送到瀑布中的第二个函数,再做10个请求等。
首先,数组我在“请求”调用之外推送所有内容都是空的,其次从每个请求返回的数据格式是不同的 - 第二部分我可以理清,但基本上我需要为了理解如何发出请求,在该请求的后面再做10个(小的,诚实的!)请求并将它们构建成一个对象。
最后,我基本上想要得到类似的东西:
{ response1:dataSet, response2:dataSet, response3:数据集 }
在将来,我可能想要添加或更改其中一些,所以任何帮助都会非常有用!我所要做的就是提出一些请求,使用他们的JSON响应构建一个对象,所以在我看来,我可以用大量的数据做我想做的事情!
由于
答案 0 :(得分:1)
让我们放大第三步,因为代码的其余部分似乎有效。问题是array.newarray.push(...)
在一个回调函数中,一旦对请求的响应进入就会调用它。节点不等待它发生,它只是在循环中发出请求,控制台.logs你的数组(当时仍为空)然后调用回调,开始下一步。然后在稍后的响应中,响应进入,回调被执行,属性被推送到该数组,但到那时为时已晚。
所以,这里需要做的是我们需要等待所有请求返回,然后调用回调进入下一步。您可以使用async执行此任务,但这次使用map操作。使用它,我们可以重写这样的步骤:
function(arg1, arg2, callback) {
var sendRequest = function(eachField, requestCallback) {
//This function will be called for each element of arg2.
request('url' + arg2.property, requestCallback);
};
async.map(arg2, sendRequest, function(err, responseArray) {
//responseArray contains the responses to all your requests.
callback(null, arg1, arg2, array);
});
}
请注意,此代码仍包含我从您的代码中接收的一些错误(例如,arg2.property
始终相同,因此您发出了许多相同的请求。)
那么这里发生了什么?我创建了一个单独的函数来实现对某个字段的实际请求。 async.map()
为arg2
的每个元素调用一次函数。它等待,直到每个sendRequest()
调用其回调结果。然后它调用作为第三个参数传递的函数,并将所有结果传递给数组。获得结果后,您可以拨打async.waterfall()
的下一步。