一些async/await在js循环里的最佳实际。

筹备工作

const entries = {  foo: 0,  bar: 1,  baz: 2,};const keys = ["foo", "bar", "baz"];const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));const getValue = (key) => sleep(1000).then((v) => entries[key]);

最佳实际 1

不要在forEach里应用await,用for循环或其余不带callback的循环代替。

// badconst run = async (_) => {  console.log('start');  keys.forEach(async key => {    const value = await getValue(key);    console.log(value)  })  console.log('end');};run();// start// end// 0// 1// 2

如果想串行执行await,应用for循环或任何不带callback的循环。

// goodconst run = async (_) => {  console.log('start');    for (let index = 0; index < keys.length; index++) {      const key = keys[index]      const value = await getValue(key)      console.log(value);    }  console.log('end')};run();// start// 0// 1// 2// end

并行执行await

// goodconst run = async (_) => {  console.log('start');  const promises = keys.map(async key => {    const value = await getValue(key)    console.log(value);  });  await Promise.all(promises)  console.log('end');};run();// start// 0 1 2// end

最佳实际 2

不要在filterreduce里应用await,能够await map返回的promise数组而后再进行filterreduce操作。

filter

const run = async (_) => {  const promises = keys.map(getValue);  const values = await Promise.all(promises)  const lessThan1 = keys.filter((key, index) => {    const value = values[index]    return value < 1  })  console.log(lessThan1);};run();// ['foo']

reduce

const run = async (_) => {  const promises = keys.map(getValue)  const values = await Promise.all(promises)  const sum = values.reduce((sum, value) => sum + value)  console.log(sum);};run();// 3

参考链接

  • JavaScript loops - how to handle async/await (lavrton.com)
  • https://zellwk.com/blog/async...