JavaScript的Iterator和Generator
- 1. Iterator
- 1.2 for-of语法糖
- 2. Generator
- 2.1 定义一个生成器函数
- 2.2 常用的方法
- 2.3 基本用法
- 2.4 传参的用法
- 2.5 异步的用法
1. Iterator
ES6 中,默认的 Iterator
接口部署在数据结构的 Symbol.iterator
属性。一个数据结构只要拥有 Symbol.iteration
属性,就是可遍历的。Symbol.iterator
是一个函数,返回当前数据结构的遍历器。Iterator
提供了 next()
方法用以返回迭代器结果对象。
let arr = ["a", "b", "c"];// 获取数组的Iterator
let symbolIterator = arr[Symbol.iterator]();// 遍历数组
let value = symbolIterator.next();
while (value.value) {console.log(value.value);value = symbolIterator.next();
}
1.2 for-of语法糖
拥有 Symbol.iteration
属性的数据结构,可以通过 for-of 遍历。
- Array
- Set
- Map
- String
- arguments 对象
- NodeList 对象
function test(param1, param2) {// 函数体内都有一个arguments对象,装着所有参数for (param of arguments) {console.log(param)}
}test(1, 2);
2. Generator
Generator
对象由生成器函数
返回。Generator
是隐藏类 Iterator
的子类。
2.1 定义一个生成器函数
// 与定义普通函数的不同在于:function关键字后面跟一个*
function* generator() {
}// 调用生成器函数,只是进行实例化,并不执行函数体的代码
let iterator = generator();
2.2 常用的方法
- next():返回
yield
表达式生成的值。 - return():类似于在当前的生成器主体的暂停位置插入
return
语句 - throw():类似于在当前的生成器主体的暂停位置插入
throw
语句
2.3 基本用法
// 定义一个 Generator 函数
function* generator() {console.log("a");// yield 表达式yield 1;console.log("b");yield 2;console.log("c");
}// 调用生成器函数,只是进行实例化,并不执行函数体的代码
let iterator = generator();// 调用 next() 开始执行函数体的代码,遇到 yield 停止执行,并返回 yield 表达式生成的值
// yield 表达式返回的是一个对象,包含 value 和 done 两个属性
let result1 = iterator.next();
console.log(result1.value);// 再调用 next(),继续执行,遇到 yield 停止执行
let result2 = iterator.next();
console.log(result2.value);// 再调用 next(),继续执行
iterator.next();
2.4 传参的用法
// 定义一个 Generator 函数
function* generator() {console.log("a");// yield表达式前面的变量param1,用来接收next()传递的参数let param1 = yield 1;console.log(param1);let param2 = yield 2;console.log(param2);
}let iterator = generator();// 第一个 next() 在遇到 yield 就停止了,此时 next() 传递的参数还没有赋值给变量 param1,并且该参数会被丢失
let result1 = iterator.next("x");
console.log(result1.value);// 第二个 next() 让代码继续执行,先把参数赋值给 param1
let result2 = iterator.next("y");
console.log(result2.value);iterator.next("z");
2.5 异步的用法
// 定义一个异步的生成器函数
async function* generator() {yield new Promise( (resolve, reject) => {// 进行异步操作setTimeout( () => {resolve("1000ms");}, 1000);} );yield new Promise( (resolve, reject) => {// 进行异步操作setTimeout( () => {resolve("2000ms");}, 2000);} );
}let iterator = generator();// async 返回的是一个promise,可以采用链式调用
// data 是一个对象,包含 value 和 done 两个属性
iterator.next().then((data) => {console.log(data);return iterator.next();
}).then((data) => {console.log(data);return iterator.next();
}).then((data) => {console.log(data);return iterator.next();
}).catch((err) => {console.log(err);
});