Generator 知识点
-
Generator 函数的执行过程,其实是将同一个回调函数,反复传入 next 方法的 value 属性。
-
Iterator 接口的 next 方法必须是同步的,只要调用就必须立刻返回值。也就是说,一旦执行next方法,就必须同步地得到value和done这两个属性。
如果遍历指针正好指向同步操作,当然没有问题,但对于异步操作,就不太合适了。
目前的解决方法是,Generator 函数里面的异步操作,返回一个 Thunk 函数或者 Promise 对象,即value属性是一个 Thunk 函数或者 Promise 对象,等待以后返回真正的值,而done属性则还是同步产生的。
Promise.resolve方法允许调用时不带参数,直接返回一个Resolved状态的Promise对象。
所以,如果希望得到一个Promise对象,比较方便的方法就是直接调用Promise.resolve方法。
使用Generator函数管理流程,遇到异步操作的时候,通常返回一个Promise对象。
Generator 函数,从语法上,可以把它理解成,是一个状态机,封装了多个内部状态。
执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield语句(或return语句)为止。
Generator函数是分段执行的,yield语句是暂停执行的标记,而next方法可以恢复执行。
yield语句后面的表达式,只有当调用next方法、内部指针指向该语句时才会执行。
一旦next方法的返回对象的done属性为true,for...of循环就会中止,且不包含该返回对象。
调用Generator函数后,该函数并不执行,而是返回一个遍历器Iterator对象。
Generator 返回的是一个遍历器Iterator对象,所以可以使用 for..of , 可以不用调用 next 方法。
function* helloWordGenerator() {
yield "hello";
yield "world";
return "ending";
}
let g = helloWordGenerator();
let first = g.next();
console.info("first.value = " + first.value); // first.value = hello
console.info("first.done = " + first.done); // first.done = false
let second = g.next();
console.info("second.value = " + second.value); // second.value = world
console.info("second.done = " + second.done); // second.done = false
let third = g.next();
console.info("third.value = " + third.value); // third.value = ending
console.info("third.done = " + third.done); // third.done = true
Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。
异步操作需要暂停的地方,都用 yield 语句注明。
Generator 函数不同于普通函数,即执行它不会返回结果,返回的是遍历器对象(指针对象)。
调用 Generator 函数,会返回一个遍历器对象(指针对象)。
调用指针 g 的 next 方法,会移动内部指针(即执行异步任务的第一段),指向第一个遇到的 yield 语句。
每次调用 next 方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield语句(或return语句)为止。
每次调用 next 方法,会返回一个对象,表示当前阶段的信息( value 属性和 done 属性)。value 属性是 yield 语句后面表达式的值,表示当前阶段的值;done 属性是一个布尔值,表示是否结束。