在ES6中,有一个名为' Generator'的新概念。它提供了一种迭代某些东西并暂停的方法,直到消费者请求下一个数据。
function *gen() {
yield 1;
yield 2;
yield 3;
}
const gen_ = gen()
gen_.next() // return 1
在gen_.next()之后,它会暂停,直到消费者gen_
请求下一个数据' 2'。
那么,发电机内部的数据何处停留?
摘要)
V8引擎内部究竟发生了什么? 如何在消费者请求下一个数据之前暂停它?那些下一个数据留在哪里?
答案 0 :(得分:1)
调用生成器函数时,会创建并返回一个迭代器对象(在代码示例中引用" gen _")。不执行生成器功能代码。
此迭代器对象用于控制生成器函数并保持生成器函数的执行上下文。迭代器对象公开了一个[[GeneratorLocation]]属性,我假设该属性跟踪生成器的程序执行暂停的位置。
通过将iterator对象引用到生成器上下文,生成器的数据保持活动,而通常在完成正常函数的程序执行后,这些数据将通过垃圾收集被丢弃(因为没有任何东西会指向它)
在迭代器上第一次调用.next()时,生成器会执行代码,直到达到yield语句。然后它返回一个新对象(在你的代码示例中){value:1,done:false}。因为done设置为false,所以迭代器对象知道工作尚未完成,因此生成器数据保持活动状态。
当程序执行暂停时,通过将生成器执行上下文从调用堆栈中取出,生成器是非阻塞的。但是它不会被丢弃,因为迭代器对象对生成器上下文的引用会使生成器数据保持活动状态。
当在迭代器上调用.next()时,发生的事情是生成器函数的执行上下文再次置于调用堆栈的顶部,继续执行它停止的执行,直到它不再有yield语句,返回一个{value:undefined,done:true}的对象。现在,迭代器对象不再指向生成器,生成器函数将从内存中丢弃。