[详见忍者秘籍第 6 章]
https://www.cnblogs.com/xiaohuochai/p/7253466.html#anchor7
1. 生成器函数的声明
function* createIterator () {
// 也可以用函数表达式来创建 var createIterator = function *(){};
// 生成器函数返回一个迭代器
}
// 生成器函数也可以作为对象的方法
var obj = {
createIterator: function *(){},
*createIterator1(){}
};
2. 调用后的返回值
- 调用生成器时,不会立即执行函数体内的代码,而是会返回一个迭代器。
- 该迭代器控制生成器代码的执行(通过执行迭代器的 next 方法);
- 该迭代器保留着一个在它创建位置处的执行上下文;之所以能从挂起状态恢复执行,是因为这个上下文一直没有被销毁,因为这个迭代器对象对它的引用一直存在;不像标准函数执行完后,对应的执行上下文会从栈中弹出,并被销毁。
3. 调用迭代器对象 的.next()
方法,会返回一个对象
{
value: [], // value 表示本次迭代的返回值
done: false // done 表示此迭代器是否迭代结束,结束时为 true,此时 value 返回 undefined
}
4. 上一步的value 和 done 的值哪里来的?
- 迭代器对象调 next 方法时的入参,会作为上一次 yield 表达式执行的返回值(所以第一次调用 next 的入参是无意义的)。
- 执行中如果遇到 return,则 return 的值也会作为 next()的 value 值,但此时 done 为 true;
- 无 return 的情况下,done 是需要检测的,例如生成器中有 2 次 yield,在第三次调用.next()时 done 才会返回 true
5. yield 关键字
- yield 关键字,只能在生成器函数中使用
- 每次调用迭代器的 next()方法,生成器会从上次挂起的地方继续运行至遇到下一个 yield 语句或 return 语句
6. 用迭代器对象实现不断重试的效果
访问数组的迭代器
a = [1,2,3];
a[Symbol.iterator]();
-
检测对象是否为可迭代对象:
String、Array、Map、Set、HTMLCollection
是,对象和数值不是function isIterable(object) { return typeof object[Symbol.iterator] === "function"; }
可迭代的对象能使用哪些语法? for-of 展开运算符(...)
迭代器对象的另一个方法:throw() 配合生成器函数中的 try/catch 块
-
迭代器对象的2个状态
suspended.png
closed.png
生成器函数能生成一组值的序列,但每个值的生成基于每次请求,并不像标准函数那样立即生成。