generators(笔记)
function*是一个用来创建generators函数的语法,调用一个generators函数将返回一个generators对象。而这个generators对象只是遵循了迭代器的接口(next、return和throw函数)
1、惰性迭代器
function* iteration() {
let index = 0;
while(true){
yield index++;
}
}
let fn = iteration();
// 无限循环
console.log(fn.next()) //{ value: 0, done: false }
console.log(fn.next()) //{ value: 1, done: false }
console.log(fn.next()) //{ value: 2, done: false }
console.log(fn.next()) //{ value: 3, done: false }
console.log(fn.next()) //{ value: 4, done: false }
如果迭代器结束了,你将会获得{ done: true }的结果
function* iteration () {
let index = 0;
while (index < 3) {
yield index++
}
}
let fn = iteration();
console.log(fn.next()); //{ value: 0, done: false }
console.log(fn.next()); //{ value: 1, done: false }
console.log(fn.next()); //{ value: 2, done: false }
console.log(fn.next()); //{ value: undefined, done: true }
2、外部控制执行
前端福利,一个令程序猿真正兴奋的特性,它可以让一个函数停止执行,并将继续执行的权利交给调用者,generators并不会在调用时执行,它只是创建一个generators对象。
function* generators () {
console.log('fn:1');
yield 0;
console.log('fn:2');
yield 1;
console.log('fn:3');
}
let fn = generators();
console.log('start');
fn.next();
console.log('break-1'); //{ value: 0, done: false }
fn.next();
console.log('break-2'); //{ value: 1, done: false }
fn.next(); //{ value: undefined, done: true }
//执行上面这段代码,你将会发现
* 输出
* start
* fn:1
* break-1
* fn:2
* break-2
* fn:3
- generators函数只有当你在generators对象上调用next方法才开始执行。
- 一旦遇到yield语句,generators将会暂停执行。
- 当next被调用时,generators会恢复执行。
- 你可以通过fn.next(value)控制yield的表达结果。
- 当yield表达式使用fn.throw(error),你可以抛出一个异常
演示控制yield的表达结果
function* generators () {
// 第一次next,value=white
let color = yield 'white';
// 第二次next,传递一个参数orag,value=orag
yield color;
// 第三次next
console.log(color); //最终打印 orag
}
let fn = generators();
console.log(fn.next()); //{ value: 'white', done: false }
console.log(fn.next('orag')); //{ value: 'orag', done: false }
console.log(fn.next()); //{ value: undefined, done: true }
演示抛出一个异常
function* generators () {
try {
yield 'bar'; //第一次next,遇到yield暂停,所以的没有打印
//抛出异常后,下面的代码将不会被执行,generatores对象终止
console.log('next');
yield 'org';
console.log('end');
} catch (err) {
// 第二次直接抛出一个异常,try终止
console.log(err.message); //打印:this is error
}
}
let fn = generators();
console.log(fn.next()); //{ value: 'bar', done: false }
// 继续执行,引发一个异常
console.log(fn.throw(new Error('this is error'))); //{ value: undefined, done: true }
console.log(fn.next()); //{ value: undefined, done: true }
总结一下
- yield允许一个generators函数暂停执行,并且将执行的权利交给外部系统。
- 外部系统可以将值推入generators函数。
- 外部系统可以将一个异常抛入generators函数。