如何按顺序将循环内的异步代码修复为 运行 程序

How to fix async code inside loop to run program in sequence

控制台日志下方的代码 false 但我希望它是 true 如何先制作异步代码运行并在循环后使用迭代值

const arr = [1, 2, 1, 2, 1, 2, 1];
let total = 0;

for (let a of arr) {
  setTimeout(() => {
    if (a === 1) {
      total++;
    }
  }, 1000);
}



if (total === 4) {
  console.log('true');
} else {
  console.log('false');
}

因为 setTimeout() 是异步的和非阻塞的,你的 for 循环只是设置了一堆定时器,然后立即 运行s 检查 total 的代码在任何计时器触发之前,因此在任何计时器递增 total 值之前。

要解决此问题,您可以将超时更改为承诺,并按顺序使用 asyncawait 到 运行 循环:

function delay(t) {
    return new Promise(resolve => {
        setTimeout(resolve, t);
    });
}

async function run() {

    const arr = [1, 2, 1, 2, 1, 2, 1];
    let total = 0;
    
    for (let a of arr) {
        await delay(1000);
        if (a === 1) {
            total++;
        } 
    }

    if (total === 4) {
        console.log('true');
    } else {
        console.log('false');
    }
}

run();

或者,运行所有并行的定时器:

function delay(t) {
    return new Promise(resolve => {
        setTimeout(resolve, t);
    });
}

async function run() {

    const arr = [1, 2, 1, 2, 1, 2, 1];
    let total = 0;

    await Promise.all(arr.map(a => {
        return delay(1000).then(() => {
            if (a === 1) total++;
        });
    }));
    
    if (total === 4) {
        console.log('true');
    } else {
        console.log('false');
    }
}

run();