Generator函数比普通javascript函数的前面多了一个星号 * ,它需要与关键字yield命令配合使用,可以实现暂停执行的功能,并且可以通过生成器的next()方法恢复执行。
下面通过一段简单的代码了解yield和Generator函数的执行过程。
测试代码1:
const testYield = function*() { let arr = [1, 2, 3]; for (let i = 0; i < arr.length; i++) { console.log(`array index: ${i}`); yield arr[i]; } }; let arkTest = testYield(); //generator的next方法原则上是可以无限次调用的,所以这里我用for循环调用5次,看看输出结果 for (let i = 0; i < 5; i++) { let obj = arkTest.next(); console.log(`yield return object: {value:${obj.value}, done:${obj.done}}`); }
执行结果:
结果分析:
第1次执行next() 输出 第1和第2行结果;
第2次执行next() 输出 第3和第4行结果;
第3次执行next() 输出 第5和第6行结果;
第4次执行next() 输出 第7行结果; 此时value已经无返回值,done标记为已完成状态
第5次执行next() 输出 第2次第7行结果;表示next可以无限次调用
接下来通过一个稍微复杂的传参示例,更加深入的理解yield和generator函数的用法。
测试代码2:
const testYield2 = function*(x) { let a = x; console.log(`step1:a=${a}`); let b = yield(a + 1); console.log(`step2:a=${a},b=${b}`); let c = yield b; console.log(`step3:a=${a},b=${b},c=${c}`); return c; } //测试数据A let arkTest2 = testYield2(5); for (let i = 0; i < 3; i++) { let obj = arkTest2.next(); console.log(`yield return object: {value:${obj.value}, done:${obj.done}}`); } //测试数据B let arkTest3 = testYield2(5); for (let i = 0; i < 3; i++) { let obj = arkTest3.next(i); //注意这里next 多了一个执行索引的参数传递进去 console.log(`yield return object: {value:${obj.value}, done:${obj.done}}`); }
测试数据A执行结果:
一开始创建testYield2的时候,传入了参数 5,
第1次执行完next(),输出第1行和第2行的结果:
第1行结果: a=x:5 的结果是:a=5;
第2行结果:返回的值是 yield(a+1):a:5+1=value:6
第2次执行完next(),输出第3行和第4行的结果:
第3行结果: b=undefined;因为第2次调用next的时候,没有传入参数,所以b=next()传入的 参数为 undefined
第4行结果:返回的值是 yield b:所以value = b 也是undefined
第3次执行完next(),输出第5行和第6行的结果:
第5行结果: c=undefined;因为第3次调用next的时候,没有传入参数,所以c=next()传入的 参数为 undefined
第6行结果:返回的值是 return c:所以value =c 也是undefined,done:true表示执行完毕
测试数据B执行结果:
一开始创建testYield2的时候,传入了参数 5,
第1次执行完next(0),输出第1行和第2行的结果:
第1行结果: a=x:5 的结果是:a=5;
第2行结果:返回的值是 yield(a+1):a:5+1=value:6
第2次执行完next(1),输出第3行和第4行的结果:
第3行结果: b=1;因为第2次调用next的时候,传入参数1,所以b=next(1)传入的 参数为 1
第4行结果:返回的值是 yield b:所以value = b 也是1
第3次执行完next(2),输出第5行和第6行的结果:
第5行结果: c=2;因为第3次调用next的时候,传入参数2,所以c=next(2)传入的 参数为 2
第6行结果:返回的值是 return c:所以value =c 也是2,done:true表示执行完毕
本文为博主原创文章,转载请附上原文出处链接和本声明,未经许可不允许商业用途和再次编辑。
本文链接:https://arky.ca/post/detail/the-use-of-yeild-and-generator-function-in-es-6-js?cate_id=4