需要尝试阻塞和异步调用
Need to try and block and asynchronous call
我正在尝试 运行 下面的代码,基本上我 运行 一个 api 调用来查看在特定时间段内有多少页的结果,运行 api 在循环中调用以从每个页面获取 return,然后在该循环中将每个结果(使用 forEach 函数)插入到 mongo 数据库中,如果 id结果大于 0。
但是,我遇到的问题是 api 调用是异步的,因此当插入函数开始为 运行 时,我收到一个失败消息,提示我正在尝试 运行 (nspResp.responses) 上的 forEach 函数未定义。
我可以通过任何方式阻止此 forEach 的 运行ning,直到 api 调用完成 运行ning 之后。我意识到我可能没有正确构建这些数据,因此重组想法也会有所帮助。
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);
});
}
});
});
}
});
}
如果您想在继续之前完成一组操作,我会将我的异步调用映射到一个承诺中,然后等待它们。例如使用下划线和 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 方法,然后映射到一个数组并收集 promise,最后在继续之前使用 Q.all 收集 promise。
我正在尝试 运行 下面的代码,基本上我 运行 一个 api 调用来查看在特定时间段内有多少页的结果,运行 api 在循环中调用以从每个页面获取 return,然后在该循环中将每个结果(使用 forEach 函数)插入到 mongo 数据库中,如果 id结果大于 0。
但是,我遇到的问题是 api 调用是异步的,因此当插入函数开始为 运行 时,我收到一个失败消息,提示我正在尝试 运行 (nspResp.responses) 上的 forEach 函数未定义。
我可以通过任何方式阻止此 forEach 的 运行ning,直到 api 调用完成 运行ning 之后。我意识到我可能没有正确构建这些数据,因此重组想法也会有所帮助。
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);
});
}
});
});
}
});
}
如果您想在继续之前完成一组操作,我会将我的异步调用映射到一个承诺中,然后等待它们。例如使用下划线和 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 方法,然后映射到一个数组并收集 promise,最后在继续之前使用 Q.all 收集 promise。