讀了這篇 Async 在 forEach、map 等各种迭代中的使用,修剪了其中的示例程序,更好理解些 for await 在干啥。

// 模拟一个耗时运算,输入 i,阻塞 i * 500 毫秒,再返回 i  
function get(i) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log("get(%d) over", i);
      resolve(i);
    }, i * 500);    
})
}

// 测试 for await
async function printNums() {
  const nums = [3, 1, 10, 2].map(n => get(n));
  console.log("begin");
  for await (const n of nums) {
    console.log("content: %d", n);
  }
}

printNums();
// will console:
begin
get(1) over
get(2) over
get(3) over
content: 3
content: 1

get(10) over
content: 10
content: 2

这样就比较清楚看出来 for await 的好处了,既异步进行了运算(耗时少的提前结束运算),又按着顺序拿到了运算的结果。从打印的日志可以看出,get(2) 提前结束了运算,仍然会等待 get(10) 计算结束之后才立即拿到结果。