yield
yield
关键字用来暂停和恢复一个生成器函数(function*
)
-
语法
-
[rv] = yield [expression];
-
expression
定义通过迭代器协议从生成器函数返回的值。如果省略,则返回undefined
。 -
rv
返回传递给生成器的next()
的可选值,以恢复其执行。
描述
-
yield
关键字使生成器函数执行暂停,yield
关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return
关键字。 -
yeild
关键字实际返回一个IteratorResult
对象 ,它有两个属性值,value
和done
。value
属性是对yield
表达式求值的结果,done
是该生成器函数是否执行完(false
未执行完,true
执行完成)。 -
一旦遇到
yield
表达式,生成器的代码将被暂停运行,直到生成器的next()
方法被调用。每一次调用生成器的next()
方法时,直到达到以下某个值:yield
,导致生成器再次暂停并返回生成器的新值。下次调用next()
时,在yield
之后紧接着的语句继续执行。throw
用于生成器中抛出异常。这让生成器完全停止执行,并在调用者中继续执行,如通常情况下抛出的异常一样。- 生成器函数执行结束,将
IteratorResult
返回给调用者,并且done
为true
。
let goTest = function* (x) {
console.log('x: ' + x);
// 执行到yield命令,返回断点位置yield后面的表达式的值
let a = yield x;
// next() 函数的参数是赋值给关键字yield后面的整个表达式。
console.log('x2: ' + x);
console.log('a: ' + a);
let b = yield(x + 1) + a;
yield a + b;
console.log('a + b = ', a+b);
return a + b;
}
go(10); // 执行这行代码, 发现console是空的。说明Generator函数
let g = goTest(10);
// 第一个next()传值无效,因为一开始还没有断点,无法接收传值。
// next()的参数是赋值给关键字yield后面的整个表达式
console.log(g.next());
// x: 10
// {value: 10, done: false}
console.log(g.next(1000));
// x2: 10
// a: 1000
// {value: 1011, done: false}
console.log(g.next(50));
// {value: 1050, done: false}
console.log(g.next(20));
// a + b = 1050
// {value: 1050, done: true}
console.log(g.next(30));
// {value: undefined, done: true}
yield*
yield*
表达式用于委托给另一个generator
或可迭代对象。
-
语法
-
yield* [[expression]];
-
expression
返回一个可迭代对象的表达式。
描述
-
yield*
表达式迭代操作数,并生产它返回的每个值。 -
yield*
表达式本身的值是当迭代器关闭时返回的值(即done
为true
时)
// 委托给其他生成器
function* g1() {
yield 2;
yield 3;
}
function* g2() {
yield 1;
yield* g1();
yield 4;
}
var iter = g2();
console.log(iter.next()); // { value: 1, done: false }
console.log(iter.next()); // { value: 2, done: false }
console.log(iter.next()); // { value: 3, done: false }
console.log(iter.next()); // { value: 4, done: false }
console.log(iter.next()); // { value: undefined, done: true }
除了生成器对象这一种可迭代对象,yield*
还可以 yield
其它任意的可迭代对象,比如说数组、字符串、arguments
对象等等。
// 委托给其他可迭代对象
function* g3() {
yield* [1, 2];
yield* "34";
yield* arguments;
}
var iter = g3(5, 6);
console.log(iter.next()); // { value: 1, done: false }
console.log(iter.next()); // { value: 2, done: false }
console.log(iter.next()); // { value: "3", done: false }
console.log(iter.next()); // { value: "4", done: false }
console.log(iter.next()); // { value: 5, done: false }
console.log(iter.next()); // { value: 6, done: false }
console.log(iter.next()); // { value: undefined, done: true }
yield*
是一个表达式,不是语句,所以它会有自己的值。
function* g4() {
yield* [1, 2, 3];
return 'foo';
}
var result;
function* g5 () {
result = yield* g4();
}
var iter = g5();
console.log(iter.next()); // { value: 1, done: false }
console.log(iter.next()); // { value: 2, done: false }
console.log(iter.next()); // { value: 3, done: false }
console.log(iter.next()); // { value: undefined, done: true },
// 此时 g4() 返回了 { value: "foo", done: true }
console.log(result); // "foo"