在 JS 中使 for 循环在没有库的情况下等待

Making a for loop wait WITHOUT a library in JS

本文关键字:情况下 等待 JS 中使 for 循环      更新时间:2023-09-26

如何在没有库(如jQuery)的情况下开始循环的新迭代之前创建一个等待异步调用完成的for循环?

例:

var items = [1,2,3,4,5];
for (var i = 0; i < items.length; i++) {
    var promise = new Promise(function(resolve, reject){
        asyncAPIcall({
            body : item[i]
        }, function(error, response){
            if(error) {
                reject();
            } else {
                resolve();
            }
        });
    promise.then(function() {
            //continue loop
        }, function() {
            //break loop
        });
}

谢谢


更新 (4/29)

我想到了这个解决方案,我创建了一个调用自己的函数:

var items = [1,2,3,4,5];
var counter = items.length - 1; //minus one since array is zero based.
function myLoop(){
    asyncAPIcall({
        body : item[counter]
    }, function(error, response){
        if(error) {
            // Error message.
        } else {
            counter = counter - 1;
            if(counter == -1){
                //Done
            }
            else {
                myLoop();
            }
        }
    });
}

您可以使用reduce使它们按顺序处理(或使用常规的for循环设置承诺链 - 我自己更喜欢reduce)。

let promise = items.reduce((carry, current) => {
    return carry.then(arr => {
        return asyncAPIcall({ body: current }).then(result => arr.concat([ result ]));
    });
}, Promise.resolve([]));
promise.then(finalResult => {
    console.log('final result:', finalResult);
});

但是,如果您实际上不需要捕获这些承诺决议的结果,这可能比您需要的要多。另请注意,您仍然会在它的末尾有一个 promise,它将包含每个 promise 的结果数组,对应于它们的原始数组位置。

另外,这是asyncAPIcall的模拟版本,如果您想跟踪方法的调用方式/位置,它应该有助于在此处显示操作顺序。

function asyncAPIcall(obj) {
    console.log('asyncAPIcall for:', obj);
    return new Promise((resolve) => {
        setTimeout(() => {
            let resolution = obj.body + 5; // change the value in some way, just to show that input !== output
            console.log('resolving with:', resolution);
            return resolve(resolution);
        }, 100);
    });
}