如何在for循环中处理异步函数和回调?

时间:2018-01-28 17:10:36

标签: javascript for-loop asynchronous callback

我有以下代码段:

var request = require('request');

var randomNumber1 = 656;
var randomNumber2 = 879;
var dataCollected = []

function printNumberOfCollectedData() {
    console.log('I collected ' + dataCollected.length + ' data so far.');
}

function getAsyncLoadedData(cb) {
    request.get('https://api.bitfinex.com/v2/candles/trade:1m:tBTCUSD/hist?limit=1&end=1517158020000&duration=1800', function (err, res, body) {
        if (err) {
            //TODO: handle err
        }
        if (res.statusCode === 200) {
            console.log(body)
            cb(body)
        } //etc
        //TODO Do something with response
    });
}

for (var n = 0; n < 1000; n++) {
    if (n === randomNumber1) {
        getAsyncLoadedData(function (data) {
            dataCollected.push(data);
        })
    }
    if (n === randomNumber2) {
        printNumberOfCollectedData();
    }
}

我的问题是 printNumberOfCollectedData 只能在 dataCollected.push(数据)之后调用; 基本上,我想冻结for循环,直到 getAsyncLoadedData 的回调被调用。

3 个答案:

答案 0 :(得分:0)

也许异步瀑布是你需要的? https://www.npmjs.com/package/async-waterfall

它提供了一个模型,其中一个接一个地执行几个回调函数,并且每个回调函数将它们的结果传递给下一个。

答案 1 :(得分:0)

您不应该使用带有异步代码的for循环。请尝试使用自我调用函数:

var max_iterations = 1000;
function loop(n) {
    if (n === randomNumber1) {
        getAsyncLoadedData(function (data) {
            dataCollected.push(data);
            setImmediate(function () { loop(n+1)});
        })
    }
    else if (n === randomNumber2) {
        printNumberOfCollectedData();
        setImmediate(function () { loop(n+1)});
     }
    else if (n < max_iterations) {
        setImmediate(function () { loop(n+1)});
    }
}

loop(0);

答案 2 :(得分:0)

我使用async / await函数解决了它。可以找到更多详细信息here。我改变了这样的代码:

async function runForLoop() {

        for (var n = 0; n < 1000; n++) {
        if (n === randomNumber1) {
            await getAsyncLoadedDataPromise(function (data) {
                dataCollected.push(data);
            });
        }
        if (n === randomNumber2) {
            printNumberOfCollectedData();
        }
    }

}
runForLoop()