Javascript的 yield(关键词),yield*(表达式)

Javascript的 yield(关键词),yield*(表达式)

yield

yield 关键字用来暂停和恢复一个生成器函数(function* )

语法

[rv] = yield [expression];

expression 定义通过迭代器协议从生成器函数返回的值。如果省略,则返回undefined

rv 返回传递给生成器的next()的可选值,以恢复其执行。

描述

yield 关键字使生成器函数执行暂停,yield 关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。

yeild 关键字实际返回一个IteratorResult对象 ,它有两个属性值,valuedonevalue属性是对yield表达式求值的结果,done是该生成器函数是否执行完(false未执行完,true执行完成)。

一旦遇到yield表达式,生成器的代码将被暂停运行,直到生成器的next()方法被调用。每一次调用生成器的next()方法时,直到达到以下某个值:

  • yield,导致生成器再次暂停并返回生成器的新值。下次调用next()时,在yield之后紧接着的语句继续执行。
  • throw 用于生成器中抛出异常。这让生成器完全停止执行,并在调用者中继续执行,如通常情况下抛出的异常一样。
  • 生成器函数执行结束,将IteratorResult返回给调用者,并且donetrue
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* 表达式本身的值是当迭代器关闭时返回的值(即donetrue时)

// 委托给其他生成器
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"

相关链接

yield
yield*

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JavaScript中,yield*是一个关键字和表达式yield*关键字用于将控制权委托给另一个生成器或可迭代对象。当使用yield*时,它会迭代并返回委托生成器或可迭代对象中的每个值,直到迭代完毕。 例如,在下面的代码示例中,函数g2委托给了函数g1,通过yield* g1(),函数g2会先返回自身的第一个值1,然后继续执行委托的函数g1,并返回g1的每个值,最后再返回g2的剩余值4。 ```javascript 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语句来产生值。在下面的代码示例中,函数outer内部使用yield* next将控制权委托给函数inner,并可以通过yield语句在inner中产生值。结果是,在调用gen.next()两次后,会依次返回'open'、'hello'、'world'和'close'。 ```javascript function* outer(next) { yield 'open'; yield* next; yield 'close'; } function* inner() { yield 'hello'; a = 2; yield 'world'; } gen = outer(inner()); console.log(gen.next()); // { value: 'open', done: false } console.log(gen.next()); // { value: 'hello', done: false } console.log(gen.next()); // { value: 'world', done: false } console.log(gen.next()); // { value: 'close', done: false } ``` 总结来说,yield*在JavaScript中用于将控制权委托给其他生成器或可迭代对象,并可以通过yield语句在委托生成器中产生值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值