生成器与迭代器
Iterator 迭代器
String、Array、Map、Set 等原生可迭代对象,因为他们都在原型(prototype)对象重实现了 Symbol.iterator 键对应的方法
for...of 是对象迭代器的遍历,而 for...in 是对象重可枚举值的遍历
我们使用的 for in
循环,是通过调用被循环对象的一个特殊函数 Iterator
来实现的,但是以前这个函数是隐藏的我们无法访问,从 Symbol 引入之后,我们就可以通过 Symbol.iterator
来直接读写这个特殊函数
var students = {};
students[Symbol.iterator] = function () {
let index = 1;
return {
next() {
return { done: index > 100, value: index++ };
},
};
};
for (var i of students) {
console.log(i);
}
Generator 生成器
用法和定义一个普通的函数(function)几乎一样,只是在 function 关键字和函数名之前加入了星号*
最大的特点是定义的函数可以被暂停执行,很类似我们打断调试代码:点击 RUN 按钮执行当前语句直到遇到下一个断点并暂停,不同的是 Generator 的这种暂停态和执行太是由代码来定义和控制的
yield 关键字用来定义代码暂停的地方,类似于给代码打断点,而 generator.next(value) 则用来控制代码的运行并出口 i 输入输出
function* getNaturalNumber() {
var seed = 0;
while (true) {
yield seed++;
}
}
var gen = getNaturalNumber(); // 实例化一个 Generator
console.log(gen.next()); // {value: 0, done: false}
console.log(gen.next()); // {value: 1, done: false}
console.log(gen.next()); // {value: 2, donw: false}
如何利用 Generator 进行异步流程控制
将异步操作用 yield 关键字进行修饰,每当执行异步操作的时候,代码便在此暂停执行了。异步操作结束后,通过在回调函数里利用 next(data) 来控制 generator 的执行流程,并顺便将异步操作的结果 data 回传给 generator,执行下一步
Generator 函数是 ES6 提供的一种异步编程解决方案
Generator 是一个可以暂停和继续执行的函数。简单的用法,可以当作一个 Iterator 来用,进行一些遍历操作。复杂一些的用法,他可以在内部保存一些状态,成为一个状态机
Generator 的基本语法包含两部分
- 函数名前要加一个星号
- 函数内部用 yield 关键字返回值
可以理解为协程,就是说多个函数互相配合完成任务,类似于这样:
function generator() {
return {
_value: [1, 2, 3, 4],
next() {
return {
value: this._value.shift(),
done: !this._value.length,
};
},
};
}
const it = generator();
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());