聊聊Generator 函数
一、 Generator 函数是什么?
Generator 函数,可以通过 yield 关键字,把函数的执行流挂起,为改变执行流程提供了可能,从而为异步编程提供解决方案。
二、 Generator 函数组成与方法
1.Generator 函数组成
Generator 有两个区分于普通函数的部分:
- 在 function 后面,函数名之前有个 * ;
- 函数内部有 yield 表达式。
2.next 方法
一般情况下,next 方法不传入参数的时候,yield 表达式的返回值是 undefined 。当 next 传入参数的时候,该参数会作为上一步yield的返回值。
2.1 next不传参数
function* gen(){
console.log("one");
yield '1';
console.log("two");
yield '2';
console.log("three");
return '3';
yield '4';
}
var f = gen();
f.next();
f.next();
f.next();
第一次调用 next 方法时,从 Generator 函数的头部开始执行,先是打印了 one ,执行到 yield 就停下来。
第二次调用 next 方法时,同上步 。
第三次调用 next 方法时,先是打印了 three ,然后执行了函数的返回操作,并将 return 后面的表达式的值,作为返回对象的 value 属性值,此时函数已经结束。
所以结果是:
2.2 next传参数
function* g(){
console.log("start");
var x = yield '1';
console.log("one:" + 2*x);
var y = yield '2';
console.log("two:" + y);
console.log("three:" + (x + y));
var z = yield '3'
}
var s = g();
s.next(10);
s.next(20);
s.next(30);
第一次调用 next 方法时,从 Generator 函数的头部开始执行,先是打印了 start ,执行到 yield 就停下来。
第二次调用 next 方法时,先把20传给x,打印出one:40,执行到 yield 就停下来。
第三次调用 next 方法时,先把30传给y,打印出two:30和three:50,然后,执行到 yield 就停下来。
所以结果是:
3.yield
- yield 表达式只能用在 Generator 函数里面,用在其它地方都会报错。
例如
function fn(){
console.log(1);
yield '1';
}
fn()
就会报语法错误,如下图所示:
- yield 表达式如果用在另一个表达式中,必须放在圆括号里面
function *fn(){
console.log('ms' + yield); // SyntaxError
console.log('ms' + yield 123); // SyntaxError
}
var f = fn()
f.next()
f.next()
就会报语法错误,如下图所示:
- yield 表达式和return语句的区别
相似:都能返回紧跟在语句后面的那个表达式的值
区别:- 每次遇到 yield,函数就暂停执行,下一次再从该位置继续向后执行;而 return 语句不具备记忆位置的功能
- 一个函数只能执行一次 return 语句,而在 Generator 函数中可以有任意多个 yield