节点js for-loop在下次迭代之前等待asynchronous函数?

我正在做一个函数,每隔一段时间刷新一次数据,而且我的请求链有问题。 问题是我有一个运行asynchronous请求的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循环不等待请求完成的事实。 我不知道的是这个解决方法。 有没有人有任何想法?

你想要asynchronous库。

例如,

 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中有很多方便的实用function,使得使用callback更容易。

为了完整性,按顺序“手动”执行asynchronous事件的方法是使用recursion:

 function dothings(things, ondone){ function go(i){ if (i >= things.length) { ondone(); } else { dothing(things[i], function(result){ return go(i+1); }); } } go(0); }