我尝试迭代抛出一个项目列表,并通过调用这个例子的API对它们执行一些操作:
for (i = 0; i < arr.length; i++) {
if (arr[i].id == 42) {
api.requestAction(arr[i].id, function(error, response){ });
}
}
问题是在所有请求完成并且程序退出之前,循环显然已经结束。我应该怎么做来管理它?我看到了#34; Promise&#34;方法,但在这种情况下我真的不知道如何使用它,或者可能还有另一种解决方案。
提前谢谢你!
答案 0 :(得分:1)
您可以使用async.js。它是一个异步控制流程库,为顺序循环,parralel中的循环以及许多其他常见的流控制机制提供控制流程,请查看它。
请参阅下面的代码,代码假设您已变量&#39; arr&#39;在范围的某处定义。
npm install async
var async = require("async");
//Loop through each item, waiting for your
//asyncronous function to finish before continuing
//to move onto the next item in the array
//NOTE: This does not loop sequentially, if you want that function with asyncjs then user eachSeries
async.each(arr,
//Item is the current item being iterated over,
//callback is the callback you call to finish the current iteration, it accepts an error and result parameter callback(error, result);
function (item, callback) {
api.requestAction(item.id, function(error, response){
//Check for any errors...
if (error) return callback(error);
callback(null);
});
},
function (err, result) {
//You've now finished the loop
if (err) {
//Do something, you passed an error object to
//in one of the loop's iterations
}
//No errors, move on with your code..
});
答案 1 :(得分:1)
使用node-fetch(一个promisify http api),您可以与async / await一起暂停for循环直到它完成,但这需要添加--harmony-async-await
标志的节点v6 +
const fetch = require('node-fetch')
async function foo() {
for (let item of arr) {
if (item.id == 42) {
let res = await fetch(url)
let body = await res.text()
console.log(body)
}
}
console.log('done (after request)')
}
现在每次在函数前面添加async关键字时,它总会返回一个在一切完成后解析/拒绝的承诺
foo().then(done, fail)
如果你不想安装node-fetch,你可以将你的api fn包裹在承诺中
await new Promise((rs, rj) => {
api.requestAction(arr[i].id, function(error, response){
error ? rj(error) : rs(response)
})
})
答案 2 :(得分:1)
安装bluebird
npm install bluebird --save
<强>代码强>
//require npm
var Promise = require("bluebird");
//code
//"promisify" converts traditional callback function into a Promise based function
var _requestAction = Promise.promisify(api.requestAction);
//loop over array
Promise.map(arr, function (value) {
if (value.id == 42) {
//async request
return _requestAction(value.id).then(function (_result) {
//success
console.log(_result);
}).catch(function (e) {
//error
console.error(e);
});
}
});
答案 3 :(得分:0)
使用蓝鸟承诺:
var Promise = require('bluebird');
Promise.map(arrayOfIds, function(item){
return api.requestAction(item);
})
.then(function(response){
// all the requests are resolved here
})
如果你想要顺序执行id,那么使用Promise.mapSeries
(在等待任务完成时很慢)