如何使用 Promises 编写异步循环?

3
我该如何使用 Promises 编写同步循环?以下两个函数在开始之前并不等待前一个循环结束...
(async ()=> {
    let arr = [3,1,2,1,2];

    const waitFor = ms => new Promise(r => setTimeout(r, ms));

    // Using Promise.all
    const firstFn = async () => { // doens't work
        return Promise.all(arr.map(async (sec) => {
            await waitFor(sec*1000);
            console.log(`waited for ${sec} seconds`);
        }));
    }
    await firstFn();

    // Using new Promise
    const secondFn = async () => {
        arr.map(sec => {
            new Promise(async (res, rej) => {
                await waitFor(sec*1000);
                console.log(`waited for ${sec} seconds`);
                res();
            });
        });
    }
    await Promise.all(secondFn());

})();

3
好的,我会尽力满足您的要求进行翻译。secondFn()函数中没有return语句,在map()函数中也都没有return - charlietfl
由于您正在使用async / await,请使用for (let sec of arr) {。数组函数不具备异步感知能力。 - Keith
你不能编写基于 Promise 的同步循环。但是你可以编写一个异步的、顺序执行的循环。 - Bergi
3个回答

1
这是一个异步函数的示例,它接受一组异步函数并按顺序执行它们。在移动到下一个函数之前等待一个函数完成。

const wait =
  ms =>
    new Promise
      ( resolve =>
          setTimeout
            ( () => (console.log(`wait ${ms}`), resolve())
            , ms
            )
      );

const async_chain =
  async ([fn, ...fns]) =>
    typeof fn === 'function'
      ? (await fn(), await async_chain(fns))
      : undefined;

(async function main() {

  await async_chain
    ( [ async () => wait(1000)
      , async () => wait(2000)
      , async () => wait(3000)
      ]
    )

})();


1

map方法可以并行处理Promise。如果想要按顺序处理,可以使用for...of或简单形式的for。例如:

async function something () {
  const arr = [3,1,2,1,2];
  for (let x = 0; x < arr.length; x++) {
    const sec = arr[x];
    await waitFor(sec*1000);
    console.log(`waited for ${sec} seconds`);
  }
}

0

谢谢。我已经用for循环写出来并且它也能正常工作,但是我想知道是否有使用Promises的方法? - wongz
请使用for ... of循环,而不是for await ... of循环! - Bergi
@wongz 这段代码使用了 Promise,waitFor 函数确实会返回一个 Promise。 - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接