简体   繁体   English

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

[英]Node js for-loop wait for asynchronous function before next iteration?

I am making a function that refreshes data every so often and I am having issues with the request chain that I have. 我正在创建一个每隔一段时间刷新一次数据的函数,而且我遇到了我的请求链问题。 The problem is that I have a for-loop running the asynchronous requests and the for-loop will finish before the requests are done. 问题是我有一个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);

If I were to run this code, it would print: 如果我要运行此代码,它将打印:

0
1
2
3
Success
Success
Success
Success

I know what the issue is. 我知道问题是什么。 It's the fact that the for-loop doesn't wait for the requests to finish. 事实是for循环不等待请求完成。 What I don't know is a work-around for this. 我不知道的是解决这个问题。 Does anyone have any ideas? 有没有人有任何想法?

For completeness, the way to do async things sequentially "by hand" is to use 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);
}

You want the async library. 你想要异步库。

For instance, 例如,

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
    });
}

Can be written like this instead: 可以这样写:

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!
});

There are lots of handy utility functions like this in async that makes working with callbacks much much easier. 在异步中有很多方便的实用程序函数,这使得回调更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Javascript:等待循环中的函数在下一次迭代之前完成执行 - Javascript: wait for function in loop to finish executing before next iteration 在 Node.js 的循环中移动到下一次迭代之前等待 Promise - Waiting for Promise before moving to next iteration in a loop in Node.js 等待函数完成,然后在Node JS中触发下一个函数 - Wait for a function to finish before firing the next in Node JS 如何在JS / JQUery中执行下一次循环迭代之前使代码等待x秒? - How to make code wait x seconds before executing next iteration of loop in JS/ JQUery? Node.js在执行功能之前需要等待循环完成 - Node.js need to wait for for loop to finish before executing function 异步 for 循环未通过 Node JS 中的第一次迭代 - Async for-loop not advancing past first iteration in Node JS 如何进行循环以等待元素,然后再进行下一次迭代 - How to make for loop wait for an element before moving to next iteration 如何在 for 循环中的下一次迭代之前等待 promise 解决 - How to wait for a promise to resolve before the next iteration in for loop 等到 http 收到请求,然后再进行下一个循环迭代 - wait until http gets request before moving to next loop iteration 强制循环等待mysql插入,然后再进行下一次迭代 - Force loop to wait for mysql insert before moving to next iteration
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM