Javascript nodejs中循环的异步问题
我试图迭代一个项列表,并通过调用API对其执行一些操作,如以下示例所示:Javascript nodejs中循环的异步问题,javascript,node.js,Javascript,Node.js,我试图迭代一个项列表,并通过调用API对其执行一些操作,如以下示例所示: for (i = 0; i < arr.length; i++) { if (arr[i].id == 42) { api.requestAction(arr[i].id, function(error, response){ }); } } (i=0;i
for (i = 0; i < arr.length; i++) {
if (arr[i].id == 42) {
api.requestAction(arr[i].id, function(error, response){ });
}
}
(i=0;i
if(arr[i].id==42){
requestAction(arr[i].id,函数(错误,响应){});
}
}
问题是循环显然在所有请求完成和程序退出之前就结束了。我应该如何管理它?我看到了“承诺”方法,但不知道如何在这种情况下使用它,或者可能还有其他解决方案
提前谢谢你 你可以用。这是一个异步控制流库,为顺序循环、parralel中的循环和许多其他常见的流控制机制提供控制流,请查看
请参阅下面的代码,该代码假设变量“arr”在范围中的某个地方定义
npm异步安装
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..
});
你可以用。这是一个异步控制流库,为顺序循环、parralel中的循环和许多其他常见的流控制机制提供控制流,请查看
请参阅下面的代码,该代码假设变量“arr”在范围中的某个地方定义
npm异步安装
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..
});
使用(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)
或者,如果您不想安装节点获取,您可以将您的api fn封装在一个承诺中
await new Promise((rs, rj) => {
api.requestAction(arr[i].id, function(error, response){
error ? rj(error) : rs(response)
})
})
使用(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)
或者,如果您不想安装节点获取,您可以将您的api fn封装在一个承诺中
await new Promise((rs, rj) => {
api.requestAction(arr[i].id, function(error, response){
error ? rj(error) : rs(response)
})
})
使用蓝鸟承诺:
var Promise = require('bluebird');
Promise.map(arrayOfIds, function(item){
return api.requestAction(item);
})
.then(function(response){
// all the requests are resolved here
})
如果您希望按顺序执行ids,请使用
Promise.mapSeries
(在等待任务完成时速度较慢)使用蓝鸟承诺:
var Promise = require('bluebird');
Promise.map(arrayOfIds, function(item){
return api.requestAction(item);
})
.then(function(response){
// all the requests are resolved here
})
如果您希望按顺序执行ids,请使用Promise.mapSeries
(在等待任务完成时速度较慢)安装
代码
//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);
});
}
});
安装
代码
//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);
});
}
});
你在使用任何
Promise
库吗?不,我没有使用它,因为我真的不知道如何处理它。@shaharyar从OP:我看到了“Promise”方法,但不知道如何在这种情况下使用它,或者可能有其他解决方案。如果我回答Promise,你会同意吗?因为最终你需要使用它。你不能完全依靠回调来生存。本例使用承诺和循环来做一些事情。您是否使用了任何Promise
库?不,我没有使用它,因为我不知道如何处理它。@shaharyar,来自OP:我看到了“Promise”方法,但不知道在这种情况下如何使用它,或者可能有其他解决方案。如果我回答Promise,您会同意吗?因为最终你需要使用它。你不能完全依靠回调来生存。这个例子使用承诺和循环来做一些事情。你的解决方案有意义,我没有看到他在停止循环,谢谢你提到你的解决方案有意义,我没有看到他在停止循环,谢谢你提到var\u requestAction=promisify.promisify(api.requestAction);这里的api.requestAction是一个函数调用。不,它是将其转换为Promise
。我添加了explaution.var _requestAction=promisify.promisify(api.requestAction);这里的api.requestAction是一个函数调用。不,它是将其转换为Promise
。我已经添加了解释。为什么要将其包装在一个闭包中?习惯的力量,刚刚移除了封装闭包:)我通常会将任何片段包装在闭包中,这样我就可以复制和粘贴代码,确保代码不会破坏目标脚本中的任何其他内容。虽然答案的可读性很好!为什么要用闭包来包装它?习惯的力量,刚刚移除了封装闭包:)我通常会用闭包来包装任何代码片段,这样我就可以复制和粘贴代码,确保代码不会破坏目标脚本中的任何其他内容。虽然答案的可读性很好!