生成器函数中的 yield 语句行为
yield statment behaviour in a generator function
学习生成器我有这个example from MDN :
function* fibonacci() {
var fn1 = 0;
var fn2 = 1;
while (true) {
var current = fn1;
fn1 = fn2;
fn2 = current + fn1;
var reset = yield current;
if (reset) {
fn1 = 0;
fn2 = 1;
}
}
}
var sequence = fibonacci();
console.log(sequence.next().value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
console.log(sequence.next().value); // 5
console.log(sequence.next().value); // 8
console.log(sequence.next(true).value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
我很欣赏一篇详尽的文字来一起回答以下问题:
为什么 reset
在所有 yield current
分配给它之后被测试为 falsy?
这就引出了一个更普遍的问题:
yield
在赋值中的表现如何?
传递给 next()
的值到底去了哪里?
因为在这段代码中
function *createIterator() {
let first = yield 1;
let second = yield first + 2; // 4 + 2
yield second + 3; // 5 + 3
}
let iterator = createIterator();
console.log(iterator.next()); // "{ value: 1, done: false }"
console.log(iterator.next(4)); // "{ value: 6, done: false }"
console.log(iterator.next(5)); // "{ value: 8, done: false }"
console.log(iterator.next()); // "{ value: undefined, done: true }"
现在我将 yield first + 2
替换为 yield (first + 2)
并且仍然得到相同的结果。那么这背后的机制是什么?
因为我是这种编程风格的新手,所以一步一步的详细答案将是很好的选择。
我为快速读者重复一遍:请帮助我理解 Javascipt 是如何逐条执行这样的代码的,谢谢
当分配 yields
时,它有两个用途:
首先是它的主要用途:
它确定迭代器的next()
方法返回的每个对象。
第二个是赋值时:
最难理解的部分是 yield 的主要作用首先在这里执行(赋值的右侧部分)。然后生成器代码冻结。下次调用 next()
时,它会恢复执行。首先将 current next()
参数分配给赋值的左侧部分。
知道那个和那个:
Each time the generator's next() method is called, the generator
resumes execution and runs until it reaches one of the following:
A yield, which causes the generator to once again pause and return the generator's new value. The next time next() is called,
execution resumes with the statement immediately after the yield.
...
这是第二个示例的执行情况:
iterator.next()--->>>
yields 1
//next returns 1 in the 'value' property
//Freezing until the next call to next
iterator.next(4)--->>>
let first =4
yield first + 2;
//next returns 6 in the 'value' property
//Freezing until the next call to next
iterator.next(5)--->>>
let second = 5
yield second + 3;
// That is 8 in the value property
有用的链接:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Advanced_generators
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next
- 一些见解和第二个示例取自 Nicholas C. Zakas 的书:Understanding ECMAScript 6
学习生成器我有这个example from MDN :
function* fibonacci() {
var fn1 = 0;
var fn2 = 1;
while (true) {
var current = fn1;
fn1 = fn2;
fn2 = current + fn1;
var reset = yield current;
if (reset) {
fn1 = 0;
fn2 = 1;
}
}
}
var sequence = fibonacci();
console.log(sequence.next().value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
console.log(sequence.next().value); // 5
console.log(sequence.next().value); // 8
console.log(sequence.next(true).value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
我很欣赏一篇详尽的文字来一起回答以下问题:
为什么 reset
在所有 yield current
分配给它之后被测试为 falsy?
这就引出了一个更普遍的问题:
yield
在赋值中的表现如何?
传递给 next()
的值到底去了哪里?
因为在这段代码中
function *createIterator() {
let first = yield 1;
let second = yield first + 2; // 4 + 2
yield second + 3; // 5 + 3
}
let iterator = createIterator();
console.log(iterator.next()); // "{ value: 1, done: false }"
console.log(iterator.next(4)); // "{ value: 6, done: false }"
console.log(iterator.next(5)); // "{ value: 8, done: false }"
console.log(iterator.next()); // "{ value: undefined, done: true }"
现在我将 yield first + 2
替换为 yield (first + 2)
并且仍然得到相同的结果。那么这背后的机制是什么?
因为我是这种编程风格的新手,所以一步一步的详细答案将是很好的选择。 我为快速读者重复一遍:请帮助我理解 Javascipt 是如何逐条执行这样的代码的,谢谢
当分配 yields
时,它有两个用途:
首先是它的主要用途:
它确定迭代器的next()
方法返回的每个对象。
第二个是赋值时:
最难理解的部分是 yield 的主要作用首先在这里执行(赋值的右侧部分)。然后生成器代码冻结。下次调用 next()
时,它会恢复执行。首先将 current next()
参数分配给赋值的左侧部分。
知道那个和那个:
Each time the generator's next() method is called, the generator resumes execution and runs until it reaches one of the following:
A yield, which causes the generator to once again pause and return the generator's new value. The next time next() is called, execution resumes with the statement immediately after the yield. ...
这是第二个示例的执行情况:
iterator.next()--->>>
yields 1
//next returns 1 in the 'value' property
//Freezing until the next call to next
iterator.next(4)--->>>
let first =4
yield first + 2;
//next returns 6 in the 'value' property
//Freezing until the next call to next
iterator.next(5)--->>>
let second = 5
yield second + 3;
// That is 8 in the value property
有用的链接:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Advanced_generators
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next
- 一些见解和第二个示例取自 Nicholas C. Zakas 的书:Understanding ECMAScript 6