循环的节点js在下一次迭代之前等待异步函数
Node js for-loop wait for asynchronous function before next iteration?
我正在制作一个每隔一段时间刷新数据的函数,但我的请求链出现了问题。问题是,我有一个运行异步请求的for循环,而for循环将在请求完成之前完成。
setInterval(function(){ // this updates the total hours of all members every 10 seconds
request({ // this gets all of the loyalty program members
url: "",//omitted
method: "GET"
},
function(listError, listResponse, listBody) {
if(listError == null && listResponse.statusCode == 200) {
var varBody = {};
var listObj = JSON.parse(listBody);
for(var i = 0; i < listObj.result.length; i++) { // parses through all of the members to update their hours
console.log(i);//****PRINT STATEMENT
varBody.index = i;
varBody.memberID = listObj.result[i].program_member.id;
request({ //we do this request to get the steam ID of the program member
url: "",//omitted
method: "GET"
},
function(fanError, fanResponse, fanBody) {
var fan = JSON.parse(fanBody);
if(fanError == null && fanResponse.statusCode == 200 && fan.result.profiles.length != 0) { // make sure that the profile isn't empty
request({
url:"",//omitted
method: "GET"
},
function(hourError, hourResponse, hourBody) {
if (hourError == null && hourResponse.statusCode == 200) {
var gameList = JSON.parse(hourBody);
var minutes = 0;
for (var j = 0; j < gameList.response.games.length; j++) { // for loop to calculate the minutes each user has on steam
minutes += gameList.response.games[j].playtime_forever;
}
var deltaHours = 1;
if(deltaHours != 0) {
var transaction = { // updated member object to be inserted
pointsearned: deltaHours,
pointsused: 0,
loyaltyprogram_id: loyaltyID,
programmember_id: memberID
};
request({ // POST request to update the member
url: "",//omitted
method: "POST",
body: JSON.stringify(transaction),
headers: {
"Content-Type": "application/json"
}
},
function(updateError, updateRes, updateBody) {
if(updateError == null && updateRes.statusCode == 200) {
console.log("Success");//****PRINT STATEMENT
}
}
);
}
}
}
);
}
}
);
}
}
console.log("Users Updated"); //****PRINT STATEMENT
}
);
}, 10000);
如果我运行这个代码,它会打印:
0
1
2
3
Success
Success
Success
Success
我知道问题出在哪里,因为for循环没有等待请求完成。我不知道的是,这是一个变通办法。有人有什么想法吗?
为了完整性,按顺序"手动"执行异步操作的方法是使用递归:
function dothings(things, ondone){
function go(i){
if (i >= things.length) {
ondone();
} else {
dothing(things[i], function(result){
return go(i+1);
});
}
}
go(0);
}
您需要异步库。
例如,
for(var i = 0; i < listObj.result.length; i++) {
varBody.index = i;
varBody.memberID = listObj.result[i].program_member.id;
request(
...
, function () {
// Do more Stuff
});
}
可以这样写:
async.forEachOf(listObj.result, function (result, i, callback) {
varBody.index = i;
varBody.memberID = result.program_member.id;
request(
...
, function () {
// Do more Stuff
// The next iteration WON'T START until callback is called
callback();
});
}, function () {
// We're done looping in this function!
});
在async中有很多像这样方便的实用程序函数,这使得处理回调变得更加容易。
相关文章:
- 如果30秒未单击,请应用CSS一次,将其删除,然后重新迭代
- JS迭代一个数组,同时更改另一个数组
- 在js中迭代一个数组,同时只将整数复制到另一个数组
- 当接收到AJAX内容时,每次$.的下一次迭代
- 为什么这个 JavaScript switch 语句(在 for 循环内)保留了上一次迭代的值
- 异步mongodb更新循环中最后一次迭代后的重定向
- for循环只迭代一次
- 使用 promises/dedelay 异步迭代一组文件
- 当我将src附加到图像时,每N秒迭代一次
- 当试图从元素中删除类时,For循环只迭代一次
- 不能让.offset()方法在迭代一组列表项时工作
- 每个函数在XML中迭代两次
- 对对象数组只迭代一次
- Javascript - for循环只迭代一次
- Angular ng-option:迭代一个数字数组,以显示另一个数组的内容,但在ng-model中选择了索引
- 迭代一个数并按降序排列
- 迭代一周中的每一天
- 迭代一次的行值并添加
- 自定义JSON.stringify不能对整个对象进行stringify,但在迭代一层时有效
- JavaScript在同一循环中每x次迭代一次循环