我正在尝试运行以下代码,基本上我运行api调用以查看在特定时间段内结果存在多少页面,在循环中运行api调用以从每个页面返回,然后在如果该结果的id大于0,则此循环将每个结果(使用forEach函数)插入到mongo数据库中。
然而,我遇到的问题是api调用是异步的,所以当插入函数开始运行时,我得到一个失败,说我正在尝试运行forEach函数的数组(nspResp.responses)是未定义。
任何方式我都可以阻止这个forEach的运行,直到api调用完成运行。我意识到我可能没有正确构建这些数据,因此重组想法也会有所帮助。
function request() {
uservoiceRequest.get({
url: "reports/user_satisfaction_responses.json",
data: {
page: 1,
start_date: "2015-01-01T00:00:00-0600",
end_date: moment().format()
}
}, function (err, respData) {
if (err) return console.log(err)
console.log(respData.pages)
for (i = 1; i <= respData.pages; i++) {
uservoiceRequest.get({
url: "reports/user_satisfaction_responses.json",
data: {
page: i,
start_date: "2015-01-01T00:00:00-0600",
end_date: moment().format()
}
}, function (err, npsResp) {
npsResp.responses.forEach(function (e) {
if (e.id > 0) {
myCollection.insert({
created_at: new Date(e.created_at),
body: e.body,
score: e.score,
id: e.id,
user: {
type: e.user.type
}
}, function (err, dataInsert) {
if (err) return console.log(err);
});
}
});
});
}
});
}
答案 0 :(得分:0)
如果你想在继续之前完成一组操作,我会将我的异步调用映射到promises中,然后等待它们。例如,使用下划线和q:
var uservoiceRequestGetPromise = q.bind(uservoiceRequest.get, uservoiceRequest)
uservoiceRequestGetPromise({
url: "reports/user_satisfaction_responses.json",
data: {
page: i,
start_date: "2015-01-01T00:00:00-0600",
end_date: moment().format()
}
}).then(function(npsResp){
var myCollectionInsertPromise = q.bind(myCollection.insert, myCollection)
return Q.all(_.map(npsResp.responses, function(e){
return myCollectionInsertPromise({
created_at: new Date(e.created_at),
body: e.body,
score: e.score,
id: e.id,
user: {
type: e.user.type
}
}
}))
}).finally(function(){
console.log('done')
})
我提供的示例有点草率,但老实说,我试图尽可能多地使用您的代码。您可以真正受益于将示例的复杂性降低到其根本原则,而不是发布您的确切代码 - 人们可以更轻松地使用和关注。
那就是说,我认为你可以将一系列NodeJs传统的回调转换成promise方法,然后映射一个数组并收集promises,最后使用Q.all也可以继续收集你的承诺。