ES6 引入了 Map,Set 等,数据结构越来越多,需要一个统一的接口来处理不同的数据结构,所以引入了迭代器,提供了统一的访问方式:for...of
循环
迭代器 IteratorES6
- 是一个对象,对象里面有
next()
方法 next()
方法返回的结果的格式必须是{ done: Boolean, value: any }
可迭代对象
是一个特殊的对象:
- 这个特殊的对象要有一个方法:
Symbol.iterator(){}
(for…of 循环启动时,就会调用这个方法) - 方法的返回值是 迭代器(Iterator)(从此开始,for…of 仅作用于这个被返回的对象)
可迭代
只要满足上面可迭代对象的条件就是可迭代的,有以下作用:
- 可以被
for...of
循环遍历 - 可用于
展开语法
- 解构赋值
yield*
Array.from()
Promise.all()
Promise.race()
内置的可迭代对象
String
Array
Map
Set
- 函数的
arguments
对象 NodeList
TypedArray
FormData
URLSearchParams
此时可以通过 for...of
循环遍历元素(解决了 for...in
遍历对象的“属性”问题以及 Set,Map 等的遍历问题)
数据转换
用途
将一个普通对象改成可迭代对象:
异步可迭代对象
与上面类似,但是可以异步地每秒返回一个值:
(1)使用 Symbol.asyncIterator
(2)next()
返回一个 promise
(3)next()
可以不是 async 函数,但是里面使用 await 更方便
(4)使用 for await...of
进行迭代
Warning
需要常规的同步 iterator 的功能,无法与异步 iterator 一起使用
例如,spread 语法无法工作:alert( [...range] ); // Error, no Symbol.iterator
Iterator 和异步 iterator 之间差异
Iterator | 异步 iterator | |
---|---|---|
提供 iterator 的对象方法 | Symbol.iterator | Symbol.asyncIterator |
next() 返回值 | 任意值 | Promise |
要进行循环,使用 | for...of | for await...of |
NOTE
for...of
会寻找同步 Iterator,for await...of
会寻找异步 Iterator。可以在一个对象中同时添加同步和异步的 Iterator,拥有 2 种迭代方式,但是这样会比较奇怪
Warning
同步 Iterator 地 next 如果返回了一个 Promise,那么
for...of
将无限循环。因为 Promise 对象不是期望的格式,for…of 循环无法正确处理它,并且认为迭代尚未完成