简体   繁体   English

在 ES6 中,“生成器”实际上是如何在 V8 引擎中暂停的?

[英]In ES6, how 'generator' actually pauses inside V8 engine?

In ES6, there is a new concept called 'Generator'.在 ES6 中,有一个名为“生成器”的新概念。 It provides a method to iterate something and pause until consumer requests next data.它提供了一种迭代某些东西并暂停直到消费者请求下一个数据的方法。

function *gen() {
  yield 1;
  yield 2;
  yield 3;
}

const gen_ = gen() 
gen_.next() // return 1

After gen_.next() it pauses until consumer gen_ requests next data '2'.在 gen_.next() 之后它会暂停,直到消费者gen_请求下一个数据“2”。 Then, where the data inside of generator stays?那么,generator 内部的数据存放在哪里呢?

Summary)概括)

What thing are actually happening inside V8 engine? V8引擎内部实际发生了什么? How can pause it until consumer request next data?如何暂停它直到消费者请求下一个数据? and where those next data stays?下一个数据在哪里?

When calling a generator function, an iterator object is created and returned (in your code example referenced by "gen_").调用生成器函数时,会创建并返回一个迭代器对象(在“gen_”引用的代码示例中)。 No generator function code is executed.不执行生成器功能代码。

This iterator object is used to control the generator function and keeps alive the execution context of the generator function.这个迭代器对象用于控制生成器函数并保持生成器函数的执行上下文。 The iterator object exposes a [[GeneratorLocation]] property which I assume keeps track of where the program execution of the generator is paused.迭代器对象公开了一个 [[GeneratorLocation]] 属性,我认为它会跟踪生成器的程序执行暂停的位置。

Through this reference of the iterator object to the generator context, the data of the generator is kept alive whereas normally after finishing program execution of a normal function, this data would be discarded through garbage collection (because nothing would point to it).通过迭代器对象对生成器上下文的引用,生成器的数据保持活动状态,而通常在完成正常函数的程序执行后,这些数据将通过垃圾收集被丢弃(因为没有任何东西指向它)。

Upon your first .next() call on your iterator, the generator executes code until it reaches a yield statement.在您的迭代器上第一次调用 .next() 时,生成器会执行代码,直到到达 yield 语句。 Then it returns a new object with (in your code example) {value: 1, done: false}.然后它返回一个新对象(在您的代码示例中){value: 1, done: false}。 Because done is set to false, the iterator object knows that work is not completed yet so the generator data is kept alive.由于 done 设置为 false,迭代器对象知道工作尚未完成,因此生成器数据保持活动状态。

When program execution is paused, the generator is non-blocking by taking the generator execution context off the call stack.当程序执行暂停时,生成器通过从调用堆栈中取出生成器执行上下文来非阻塞。 It is however not discarded because the reference of the iterator object to the generator context keeps the generator data alive.然而它不会被丢弃,因为迭代器对象对生成器上下文的引用使生成器数据保持活动状态。

When calling .next() on the iterator what happens is that the execution context of the generator function is again placed on top of the call stack, continuing the execution where it left off until it reaches no more yield statements, returning an object with {value: undefined, done: true}.在迭代器上调用 .next() 时发生的情况是生成器函数的执行上下文再次放置在调用堆栈的顶部,从中断处继续执行,直到没有更多的 yield 语句,返回一个带有 { 的对象值:未定义,完成:真}。 Now the iterator object won't point to the generator anymore and the generator function is discarded from memory.现在迭代器对象不再指向生成器并且生成器函数从内存中被丢弃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM