Generator 函数是 ES6 提供的一类特殊函数,在运行期间可以被打断,也就是说在运行期间,可以暂停去执行其他代码,可以一次或多次启动和停止。
Generator 函数有两个特征:
1、function 关键字与函数名之间有一个 * 号;
2、在函数内部使用 yield表达式 来定义状态。
* 号放在哪?
* 号的位置放在哪里都是可以的:
-
function* webFn();
-
function *webFn();
-
function*webFn();
三种代码风格,用哪一种都是可以的,小项目是风格偏好问题,大项目视情况而定「Code Review」。
先来实现一个最简单的 Generator 函数
function *webFn(){
yield 1+1;
yield 2+2;
}
var it = webFn();
it.next();//启动并执行;第一条 yield 输出:2
it.next();//第二条 yield 输出:4
yield => 暂停。后面可以跟「表达式」,如果后面有「表达式」,执行的时候就会执行表达式;
next => 继续执行。会执行相对应位置 yield 后面的表达式;
next() 方法会返回一个对象「Object」,对象里面有两个参数:
value = next().value => 结果值
done = next().done => 遍历是否结束
再看一个简单的例子:
function *webFn(x){
var y = x * (yield);
return y;
}
var it = webFn(6);
it.next();//启动 undefined
var it2 = it.next(7);
it2.value;//执行 x=6 y=7 输出 42
it.next() 启动并且暂停。it.next(7) 7代表的是之前的 yield 表达式的结果。
那就是 var y = 6 * 7;
多个迭代器「yield」的例子:
function *web(x) {
var y = 2 * (yield (x + 1));
var z = yield (y * 3);
return (x + y + z);
}
var it = web(5);
it.next();//Object{value:6, done:false}
it.next();//Object{value:NaN, done:false}
拆解:a = web(5) 先构造一个迭代器。
第一个 next() 启动生成器,执行第一个 yield 后面的表达式(x+1),输出 6 ,暂停;
第二个next() 执行第二个 yield 后面的表达式,它 next() 里面没有传参数,所以是 undeined * 3 ,结果为 NaN。
如果 yield 后面写的是「字符串」,那就会直接输出字符串。
-备注-
第一个 next(),不需要传参数,传参也不起作用的。
那如果 next() 里面传了参数呢?那 yield 表达式就需要重新赋值了。看一个例子:
function* web(x) {
var y = 2 * (yield (x + 1));
var z = yield (y * 3);
return (x + y + z);
}
var it = web(5);
it.next();//Object{value:6, done:false}
it.next(5);//Object{value:30, done:false}
it.next(1);//Object{value:16, done:true}
拆解:
第一个 next() 不需要传参数,启动并输出 6;
第二个 next(5) 传入 5 ,上一个 yield 表达式 yield (x + 1) = 5;所以会执行 var y = 2 * 5;现在 y = 10;执行下一个 yield 表达式 10 * 3,输出结果 30;
第三个 next(1) 传入 1,上一个 yield 表达式(y * 3)= 1,所以 z = 1;再之前的 next(5) ,第一个 yield 结果为5,执行 var y = 2 * 5,y = 10; web(5) 定义x=5;最终 5 + 10 + 1,输出 16。
有点乱,对于代码的执行没找到好的「文字输出方案」… 略表遗憾。
上面几个案例,展示了最基本的 Generator 函数的使用方法和小技巧。
还有 yield* 、throw、return 等等方法都值得去看看,也有 Promise 配合的异步、并发(我也不会)有真实应用场景,如果有机会的话,我会找时间写一写。
当然了,程序员嘴里的「如果有时间,我就怎样怎样…」你知道,这不大靠谱。
参考资料:
《你不知道的 JavaScript 中 》
http://es6.ruanyifeng.com/#docs/generator
原创文章,作者:小道研究,如若转载,请注明出处:https://www.sudun.com/ask/34559.html