for of与for await of的区别:为何普通数组测试结果一致?
为什么ECMA要制定
for await of语法? 首先看你用到的返回Promise的timer函数:
const timer = (time) => { return new Promise((resolve, reject) => { console.log(`${time} timer start`); setTimeout(() => { console.log(`${time} timer end`); resolve(); }, time); }); };
你用普通数值数组分别测试了for await of和for of加await的写法:
使用for await of的代码
async function runForAwaitOf() { const times = [300, 100, 700, 500]; for await (let time of times) { await timer(time); } console.log('All the timers end'); } runForAwaitOf()
使用for of的代码
async function runForOf() { const times = [300, 100, 700, 500]; for (let time of times) { await timer(time); } console.log('All the timers end'); } runForOf()
你发现两者执行结果一致,所以疑惑为什么需要for await of语法——原因很简单:你当前测试的是普通同步数组,这种场景下两者效果确实重合,但for await of的核心作用是处理异步可迭代对象,这是for of加手动await没法优雅解决的场景。
具体适用场景举例:
- 异步生成器
如果有一个返回Promise序列的异步生成器:
async function* asyncTimerGenerator() { yield timer(300); yield timer(100); yield timer(700); yield timer(500); }
用for of遍历的话,拿到的是一个个Promise实例,必须手动加await:
async function runWithForOf() { for (const promise of asyncTimerGenerator()) { await promise; } console.log('All done'); }
而用for await of的话,会自动等待每个Promise完成,代码更简洁直观:
async function runWithForAwaitOf() { for await (const _ of asyncTimerGenerator()) { // 无需手动处理await,语法自动完成异步等待 } console.log('All done'); }
- 原生异步可迭代对象
比如Node.js中的文件读取流,它本身是异步可迭代对象,用for await of可以直接逐块读取数据,不需要监听data事件:
const { createReadStream } = require('fs/promises'); async function readFileStream() { const stream = createReadStream('example.txt', { encoding: 'utf8' }); for await (const chunk of stream) { console.log('读取到数据块:', chunk); } }
这种场景下for of无法直接使用,因为迭代器返回的是Promise,必须依赖for await of来处理异步迭代逻辑。
总结
for await of不是为了替代同步数组场景下的for of加await,它是专门为异步迭代场景设计的语法糖,让异步可迭代对象的遍历代码更简洁、逻辑更贴近同步迭代的写法,解决了for of无法直接处理异步迭代器的问题。
内容的提问来源于stack exchange,提问作者jspking
相关产品推荐
相关产品推荐

