function * f () {
yield 2;
}
function * test () {
try {
yield 1;
yield * f(); // 等同于for ... of
for (let i of f()) {
console.log('执行了for ... of')
yield i;
}
yield 3;
} catch (e) {
console.log(e)
}
yield 4; // 内部捕获到错误会执行一遍s.next(),所以会把4输出
return 5; // 如果没有return的话,会返回undefined
}
let s = test();
s.next(); //{value: 1, done: false}
s.next(); //{value: 2, done: false}
s.next(); //执行了for ... of {value: 2, done: false}
s.next(); //{value: 3, done: false}
s.throw(); //{value: 4, done: false}
s.next(); //{value: 5, done: true}
s.next(); //{value: undefined, done: true}
//throw方法抛出的错误要被内部捕获,前提是必须至少执行过一次next方法
代码结果:
抓重点:下面几个就是组成generator函数的关键词
1、function *
2、yield
3、yield *
4、for … of
5、next()、throw()、return
我们先上一段阮一峰老师描述的generator函数:
1、Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同;
2、Generator 函数是一个状态机,封装了多个内部状态;
3、Generator 函数会返回一个遍历器对象...
下面简短的介绍一下组成Generator函数的几个部分(下面的内容里把Generator函数简称为G函数)
1、function *
G函数的第一个特征:必须在function关键词和函数名之间带一个星号
2、yield
G函数的第二个特征:函数体内部使用yield表达式(定义状态)
作用:
1、执行next(),代码调用到yield表达式,暂停;再执行next(),到下一个yield表达式。。。依次类推
2、next()遇到yield表达式还会再执行下面的代码;遇到return就不会再执行之后的代码了
3、yield只能在G函数中使用
4、yield用在别的表达式中必须要加括号
注意的部分:G函数的调用和一般函数一样,不同点:不执行内部的代码,返回的是一个内部状态的指针对象(遍历器对象)
3、yield *
在G函数内部,调用另一个G函数。等同于for … of循环的作用
4、for … of
自动遍历G函数运行时生成的遍历器对象,且此时不再需要调用next方法
5、next()、throw()、return()
const g = function* (x, y) {
let result = yield x + y;
return result;
};
const gen = g(1, 2);
gen.next(); // Object {value: 3, done: false}
gen.next(1); // Object {value: 1, done: true}
// 相当于将 let result = yield x + y
// 替换成 let result = 1;
gen.throw(new Error('出错了')); // Uncaught Error: 出错了
// 相当于将 let result = yield x + y
// 替换成 let result = throw(new Error('出错了'));
gen.return(2); // Object {value: 2, done: true}
// 相当于将 let result = yield x + y
// 替换成 let result = return 2;
next()是将yield表达式替换成一个值
throw()是将yield表达式替换成一个throw语句
return()是将yield表达式替换成一个return语句
应用
1、异步操作同步处理
2、控制流管理(按次序执行代码)
遇到问题可以评论留言,欢迎一起讨论问题!