基本概念
执行 Generator 函数会返回一个遍历器对象,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }value属性就是当前yield表达式的值hello,done属性的值false,表示遍历还没有结束
hw.next()
// { value: undefined, done: true }
定义了一个 Generator 函数helloWorldGenerator,它内部有两个yield表达式(hello和world),即该函数有三个状态:hello,world 和 return 语句(结束执行)。
调用 Generator 函数后,该函数并不执行,返回是一个指向内部状态的指针对象。
调用遍历器对象的next方法,使得指针移向下一个状态。每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。
yield表达式是暂停执行的标记,next方法可以恢复执行。
遍历器对象的next方法的运行逻辑如下。
(1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。
(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。
(3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。
(4)如果该函数没有return语句,则返回的对象的value属性值为undefined。
不用yield表达式,就变成一个单纯的暂缓执行函数
function* f() {
console.log('执行了!')
}
var generator = f();
setTimeout(function () {
generator.next()
}, 2000);
yield表达式只能用在 Generator 函数里面
与 Iterator 接口的关系
任意一个对象的Symbol.iterator方法,等于该对象的遍历器生成函数,调用该函数会返回该对象的一个遍历器对象。
把 Generator 赋值给对象的Symbol.iterator属性,从而使得该对象具有 Iterator 接口。
next 方法的参数
next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
要第一次调用next方法时,就能够输入值,可以在 Generator 函数外面再包一层
for…of 循环
for…of循环可以自动遍历 Generator 函数运行时生成的Iterator对象,且此时不再需要调用next方法
for…of循环,扩展运算符(…)、解构赋值和Array.from方法内部调用的,都是遍历器接口。它们都可以将 Generator 函数返回的 Iterator 对象,作为参数。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)