JavaScript – Async Iterator & Generator
前言
要看懂这篇请先看下面几篇
JavaScript – Generator Function
JavaScript – 用 Generator 运行异步函数 & await async
Async Iterator (es2018)
es6 推出的 Iterator + for...of 非常好用, 但是它只能执行同步代码. 不支持异步编程.
顾名思义 Async Iterator 就是 Iterator 的 Async 版本. 它支持异步编程.
我们来看看 sync 和 async Iterator 的对比
sync Iterable
const iterable: Iterable<string> = { [Symbol.iterator]() { let index = 0; return { next() { index++; if (index === 10) { return { done: true, value: '', }; } return { done: false, value: 'value' + index }; }, }; }, }; for (const value of iterable) { console.log('value', value); }
async Iterable
const asyncIterable: AsyncIterable<string> = { [Symbol.asyncIterator]() { let index = 0; return { async next() { return new Promise((resolve) => { setTimeout(() => { index++; if (index === 10) { resolve({ done: true, value: '', }); } return resolve({ done: false, value: 'value' + index }); }, 1000); }); }, }; }, }; (async () => { const asyncIterator = asyncIterable[Symbol.asyncIterator](); const { value, done } = await asyncIterator.next(); console.log([value, done]); for await (const value of asyncIterable) { console.log('value', value); } })();
和 sync iterable 的区别是
1. 属性是 Symbol.asyncIterator
2. iterator next 返回的是一个 promise, promise 的返回才是 done 和 value
3. 遍历的方式是 for await ... of
你可能会认为, sync iterable 也可以返回 promise 丫.
的确. 在 JavaScript – 用 Generator 运行异步函数 & await async 里有提到如何用 Generator + Iterator + Promise + 自执行 Generator 来实现异步编程 (async await 语法糖的背后的原理)
它的 iterator next value 返回的就是 promise. 但不要忘了, 还有 done 属性呢? 这个总不能返回 Promise 了丫. 所以还是有细微区别的.
Async Generator (es2018)
和 Async Iterator 一样概念. Generator 也有 Async 版本.
function delayAsync(time: number, value: string) { return new Promise((resolve) => { setTimeout(() => { resolve(value); }, time); }); } async function* myGenerator() { yield delayAsync(1000, 'a'); console.log('do something'); yield delayAsync(1000, 'b'); } (async () => { const asyncIterator = myGenerator(); for await (const value of asyncIterator) { console.log(value); } // 1000ms after log a // do something // another 1000ms after log b })();
和 sync Generator 的区别是
1. async function* 多了 async 关键字开头
2. yield 返回 Promise
3. 可以用 for await...of 遍历
for...of + Promise.all 对比 for await...of
当有一堆 promises 想 loop 的时候, 在 for await...of 出现前. 通常是搭配 Promise.all 来使用的
const promises = [delayAsync(1000, 'a'), delayAsync(2000, 'b')]; (async () => { for (const value of await Promise.all(promises)) { console.log(value); } for await (const value of promises) { console.log(value); } })();
几时知识点:
1. 当 delayAsync 调用时, setTimeout 马山就执行了. 所以下面这 2 个 timeout 是一起 start 的哦
const promises = [delayAsync(1000, 'a'), delayAsync(2000, 'b')];
2.
for (const value of await Promise.all(promises)) { console.log(value); }
await Promise.all 返回 array 后才进入 for...of. 所以在 2 秒钟后 log a 和 log b 会马上执行 (同步, 中间没有间隔时间)
3.
for await (const value of promises) { console.log(value); }
和 for...of 不同, 它会先去 loop, 所以会先拿出第一个 promise, 等待. 1 秒钟后就会执行 log a.
然后再拿第 2 个 promise. 这时 promise2 已经过去 1 秒了, 所以再 1 秒钟后就会只是 log b.
一定要搞清楚它们执行的顺序和时机哦.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
2015-05-22 angularjs directive and component 指令与组件 ( 1.5.0 以后 )