【问题标题】:Understanding how the yield impacts the return value in a JS generator了解产量如何影响 JS 生成器中的返回值
【发布时间】:2019-10-12 13:17:08
【问题描述】:

假设我有一些功能如下:

function *hello(x) { // define generator
  while (x < 7) {
	console.log(`before: ${x}`)
    x += yield x + 1; // generator object will have value x + 1, then next step of generator has value x + x and not x + x + 1
	console.log(`after: ${x}`)
  }
  return x; 
}
var world = hello(3);
console.log( world.next(2) ); 
console.log( world.next(2) ); 
console.log( world.next(2) );
console.log( world.next(2) );

// before: 3
// {value: 4, done: false}
// after: 5
// before: 5
// {value: 6, done: false}
// after: 7
// {value: 7, done: true}
// {value: undefined, done: true}

我可以看到带有yield的行返回了一个值为x + 1的生成器对象,但x的实际值只增加了x,而不是x+1,可以这样通过beforeafter 控制台日志中的值看到。为什么x 的值在yield 的右侧被添加到x 的当前值,而+ 1 不是?我知道x 的值是要添加的,因为如果我在next 函数中更改传递给生成器对象的值,则之前和之后的值反映了x 增加了多少。

function *hello(x) { // define generator
  while (x < 7) {
	console.log(`before: ${x}`)
    x += yield x + 1; // generator object will have value x + 1, then next step of generator has value x + x and not x + x + 1
	console.log(`after: ${x}`)
  }
  return x; 
}
var world = hello(3);
console.log( world.next(1) ); 
console.log( world.next(1) ); 
console.log( world.next(1) );
console.log( world.next(1) );

// before: 3
// {value: 4, done: false}
// after: 4
// before: 4
// {value: 5, done: false}
// after: 5
// before: 5
// {value: 6, done: false}
// after: 6
// before: 6
// {value: 7, done: false}
// after: 7
// {value: 7, done: true}
// {value: undefined, done: true}

【问题讨论】:

    标签: javascript ecmascript-6 generator


    【解决方案1】:

    表达式的值:

    x += yield x + 1;
    

    不是x + 1。值x + 1 是给调用者的。生成器中yield 的值是传入的值。在这种情况下,它始终是1,因为这是传递给它的值:

    world.next(1)
    

    发电机一碰到yield就会停止,所以在这种情况下

    x += yield x + 1;
    

    你可以把它想象成这样:

    yield x + 1; // pass this value to the called
    
    [Pause]
    
    [Next call from  world.next(1)]
    
    x = 1 // value passed in from caller
    

    【讨论】:

    • 那么,在将表达式x+1 让给生成器对象之后,基本上就好像yield 右侧的所有内容在代码执行恢复时都被删除了?
    • 是的,@emijune 右侧不是表达式值的一部分。您可以将 yield 视为类似于将表达式返回到右侧。然后等待输入传到左边。
    • 知道了。因此,假设我确实想增加 x + 1,我会将语句修改为 yield x += x + 1 而不是`x += yield x + 1`。有道理,谢谢!
    • 是的@emijune,也可以选择从外部将 x 传回生成器:let g = hello(0); world = g.next(world.value)world.done 为假。这会将x+1 传递回生成器。
    猜你喜欢
    • 2017-05-10
    • 2023-03-10
    • 2015-06-07
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 2021-06-22
    相关资源
    最近更新 更多