Neu*_*onQ 4 javascript yield generator
将参数传递给next()ES6生成器时,为什么忽略第一个值?更具体地讲,为什么这个输出x = 44而不是x = 43:
function* foo() {
let i = 0;
var x = 1 + (yield "foo" + (++i));
console.log(`x = ${x}`);
}
fooer = foo();
console.log(fooer.next(42));
console.log(fooer.next(43));
// output:
// { value: 'foo1', done: false }
// x = 44
// { value: undefined, done: true }
Run Code Online (Sandbox Code Playgroud)
我对这种生成器的行为的心理模型是这样的:
foo1并在yield处暂停(next返回的调用foo1将作为参数42)nextvar x = 1 + 42因为这是先前收到的参数x = 43{done: true}从最后一个返回a next,而忽略其参数(43)并停止。现在,显然,这不是正在发生的事情。所以... 我在这里怎么了?
我最终编写了这种代码来更彻底地调查行为(在重新阅读了有关generators的MDN文档之后):
function* bar() {
pp('in bar');
console.log(`1. ${yield 100}`);
console.log(`after 1`);
console.log(`2. ${yield 200}`);
console.log(`after 2`);
}
let barer = bar();
pp(`1. next:`, barer.next(1));
pp(`--- done with 1 next(1)\n`);
pp(`2. next:`, barer.next(2));
pp(`--- done with 2 next(2)\n`);
pp(`3. next:`, barer.next(3));
pp(`--- done with 3 next(3)\n`);
Run Code Online (Sandbox Code Playgroud)
输出以下内容:
in bar
1. next: { value: 100, done: false }
--- done with 1 next(1)
1. 2
after 1
2. next: { value: 200, done: false }
--- done with 2 next(2)
2. 3
after 2
3. next: { value: undefined, done: true }
--- done with 3 next(3)
Run Code Online (Sandbox Code Playgroud)
因此,显然正确的心理模型是这样的:
在第一次调用next时,函数发生器体被运行到所述yield表达式中,“参数”的yield(100第一次)被返回作为返回的值next,和所述发电机体暂停之前评估产量表达式的值 -在“之前”部分是关键
仅在第二呼叫,以next在所述的值第一 yield计算/替换为给定的距离下在一个参数的值表达此呼叫(不与在给定的一个前一个如我所料),和执行运行,直到第二yield,并next返回第二个yield的参数的值- 这是我的错误:我假设第一个yield表达式的值是第一次调用next的参数,但实际上是第二次调用next的参数,或者以另一种方式确切地说,它是在执行期间实际计算值的调用的参数next
这对谁发明了这个方法更有意义,因为对#的调用next次数是yield语句数量的一倍以上(还有最后一个返回{ value: undefined, done: true }信号终止),因此,如果不会忽略第一个调用的参数,则最后一个调用将不得不被忽略。同样,在评估next主体时,替换将从其先前调用的参数开始。这本来是更直观的恕我直言,但我认为这也是遵循其他语言的生成器约定,而一致性最终是最好的……
没意思,但很有启发性:刚刚尝试在Python中做同样的探索,它显然实现了类似于Javascript的生成器,TypeError: can't send non-None value to a just-started generator当我尝试将参数传递给第一个调用时,我立即得到了一个提示next()(清楚地表明我的心智模型是错误的!) ,并且迭代器API也以抛出StopIteration异常结束,因此不需要“额外” next()就可以检查a是否done为真的(我想使用此额外的调用来利用副作用的最后一个下一个参数只会导致非常难以理解和调试代码...)。比在JS中更容易“摸索”。
| 归档时间: |
|
| 查看次数: |
387 次 |
| 最近记录: |