- 基本概念
Generator(生成器)函数就是ES6提供的一种异步编程解决方案,并且Generator 函数的行为与传统函数完全不同。 - 执行Generator函数,函数本身不会执行,而是返回一个 遍历器对象,同时该对象是可遍历的。因为在其原型链上也具有Symbol.iterator方法,并且该方法返回的对象就是该遍历器对象自身。
function* func(){
console.log("one");
}
let a = func()
a[Symbol.iterator]() === a //true
执行机制:
function* func (param) {
console.log("one");
yield '1';
console.log("two");
yield '2';
console.log("three");
return '3';
}
let a = func()
Generator 原型链上有next()方法,所以打印输出如下:
a.next();
// one
// {value: "1", done: false}
a.next();
// two
// {value: "2", done: false}
a.next();
// three
// {value: "3", done: true}
a.next();
// {value: undefined, done: true}
- 函数返回的遍历器对象的方法
next 方法不传入参数的时候,yield 表达式的返回值是 undefined 。当 next 传入参数的时候,该参数会作为上一步yield的返回值。
function* sendParameter(){
console.log("start");
var x = yield '2';
console.log("one:" + x);
var y = yield '3';
console.log("two:" + y);
console.log("total:" + (x + y));
}
next不传参:
var sendp1 = sendParameter();
sendp1.next();
// start
// {value: "2", done: false}
sendp1.next();
// one:undefined
// {value: "3", done: false}
sendp1.next();
// two:undefined
// total:NaN
// {value: undefined, done: true}
next传参:
var sendp2 = sendParameter();
sendp2.next(10);
// start
// {value: "2", done: false}
sendp2.next(20);
// one:20
// {value: "3", done: false}
sendp2.next(30);
// two:30
// total:50
// {value: undefined, done: true}
- return 方法
return 方法返回给定值,并结束遍历 Generator 函数。
return 方法提供参数时,返回该参数;不提供参数时,返回 undefined 。
function* foo(){
yield 1;
yield 2;
yield 3;
}
var f = foo();
f.next();
// {value: 1, done: false}
f.return("foo");
// {value: "foo", done: true}
f.next();
// {value: undefined, done: true}
- throw 方法
throw 方法可以再 Generator 函数体外面抛出异常,再函数体内部捕获。
var g = function* () {
try {
yield;
} catch (e) {
console.log('catch inner', e);
}
};
var i = g();
i.next();
try {
i.throw('a');
i.throw('b');
} catch (e) {
console.log('catch outside', e);
}
// catch inner a
// catch outside b
遍历器对象抛出了两个错误,第一个被 Generator 函数内部捕获,第二个因为函数体内部的catch 函数已经执行过了,不会再捕获这个错误,所以这个错误就抛出 Generator 函数体,被函数体外的 catch 捕获。