- 看上去像一个函数,但可以返回多次。
- Generator 函数会返回一个遍历器对象。
function* gen() {
yield 'Hello';
yield 'Hi';
return 'return';
}
console.log(gen())
Generator.prototype.next()
function* gen() {
yield 'Hello';
yield 'Hi';
return 'return';
}
var g = gen();
console.log(g.next())
//Object { value: "Hello", done: false }
//value 表示当前yield表达式的值
//done false表示遍历还没有结束
console.log(g.next())
//Object { value: "Hi", done: false }
console.log(g.next())
//Object { value: "return", done: true }
//done true表示遍历结束啦
console.log(g.next())
//Object { value: undefined, done: true }
-
next带参数。该参数就会被当作上一个
yield
表达式的返回值。 -
function* foo(x) { var y = 2 * (yield (x + 1)); var z = yield (y / 3); return (x + y + z); } var a = foo(5); a.next() // Object{value:6, done:false} a.next() // Object{value:NaN, done:false} a.next() // Object{value:NaN, done:true} var b = foo(5); b.next() // { value:6, done:false } b.next(12) // { value:8, done:false } b.next(13) // { value:42, done:true }
yield
yield
表达式后面的表达式,只有当调用next
方法、内部指针指向该语句时才会执行,因此等于为 JavaScript 提供了手动的“惰性求值”(Lazy Evaluation)的语法功能。-
function* gen() { yield 'Hello'; yield 200 + 100;//等next到了这语句的时候 后面的表达式才执行 return 'return'; }
- 每次遇到
yield
,函数暂停执行,下一次再从该位置继续向后执行 - Generator 函数可以不用
yield
表达式,这时就变成了一个单纯的暂缓执行函数。
function* gen2() {
console.log('hi');
//三秒后输出 hi
// return 'Hi';
}
var g2 = gen2();
setTimeout(()=>{
g2.next()
},3000)
- 在普通函数中不能使用
yield
表达式。 yield
表达式如果用在另一个表达式之中,必须放在圆括号里面。console.log('Hello' + (yield))
for...of
for...of
循环可以自动遍历 Generator 函数运行时生成的Iterator
对象,且此时不再需要调用next
方法。
function* foo() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
return 6;
}
for (let v of foo()) {
console.log(v);
}
// 1 2 3 4 5
Generator.prototype.throw()
向生成器抛出一个错误。
var g = function* () {
while (true) {
try {
yield;
} catch (e) {
if (e != 'a') throw e;
console.log('内部捕获', e);
}
}
};
var i = g();
i.next();
try {
throw new Error('a');
throw new Error('b');
} catch (e) {
console.log('外部捕获', e);
}
// 外部捕获 [Error: a]
Generator.prototype.return()
可以返回给定的值,并且终结遍历 Generator 函数。
如果 Generator 函数内部有try...finally
代码块,且正在执行try
代码块,那么return()
方法会导致立刻进入finally
代码块,执行完以后,整个函数才会结束。
yield*
用来在一个 Generator 函数里面执行另一个 Generator 函数。
function* inner() {
yield 'hello!';
}
function* outer1() {
yield 'open';
yield inner();
yield 'close';
}
var gen = outer1()
gen.next().value // "open"
gen.next().value // 返回一个遍历器对象
gen.next().value // "close"
function* outer2() {
yield 'open'
yield* inner()
yield 'close'
}
var gen = outer2()
gen.next().value // "open"
gen.next().value // "hello!"
gen.next().value // "close"