generator是一个普通函数,有两个特征。一是,funtion关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式。
generator英语中的意思是生成器,yield英语中的意思是产出
function* aa() {
yield 'b'
}
1.yield表达式
yield表达式与return语句类似,都能返回紧跟在语句之后的表达式的值。区别在于yield表达式,是暂停执行,下次会从该位置继续执行,return则不具备记忆功能,没法继续执行。 而且yield表达式只能用在generator函数中。
yield表达式用在另一个表达式中,必须放在圆括号里
console.log('hello' + (yield 123))
yield表达式用做函数参数,或者放在赋值表达式的右边可以不加括号。
yield表达式本身没有返回值,或者返回值是undefined。next()方法可以传入一个参数,该参数会被当作上一个yield表达式的返回值。 所以第一次调用next()时参数是无效的。
2.Generator.prototype.throw()
Generator函数放回的遍历器对象,都有一个throw方法,可以在函数体外抛出错误,然后在Generator函数体内捕获。
function* g() {
try{
yield;
} catch (e) {
console.log('内部捕获',e)
}
}
let i = g();
i.next();
i.throw('a') //建议 i.throw(new Error("出错了"))
throw()方法可以接受一个参数,该参数会被catch语句接收,建议抛出Error对象的实例。
throw()方法抛出的错误要被内部捕获,前提是必须执行过next()方法。
如果Generator函数内部没有try...catch代码块,那么throw()方法抛出的错误,会被外部的try...catch代码块捕获。
另外throw()方法具有next()方法的功能,也就是说throw()方法执行的时候,会附带执行一次next()方法。
3.Generator.prototype.return()
返回给定的值,并终结遍历Generator函数。同样renturn()方法也可以传入参数,然后作为最后的返回值,如果return方法没有传入参数,则返回值的value属性为undefined.
如果Generator函数内部有try...finally代码块,且正在执行try代码块,那么return方法会推迟到finally代码块执行完在执行。
4. yield* 表达式
用来解决在一个Generator函数里面执行另一个Generator函数。
从语法角度看,如果yield表达式后面跟的是一个遍历器对象,需要在yield表达式后面加上星号,表明它返回的是一个遍历器对象。实际上,任何数据结构只要有Iterator接口,就可以被yield*遍历。