ERROR: Generator is already running
与之关联的另一种报错是:
TypeError: Iterator result undefined is not an object
问题解读
这是 v6.9.1 版本在和谐模式下运行时出现的一个现象。来看源代码
// foo.js
'use strict';
function foo() {
console.log('foo invoked');
}
var G = function*() {
// KEY LINE
return foo();
}
var gen = G();
console.log(gen.next());
try {
gen.next();
} catch(ex) {
console.log('[ERROR] ' + ex.message);
}
普通模式下执行上述程序的输出如下:
node foo.js
# OUTPUT
# foo invoked
# { value: undefined, done: true }
# { value: undefined, done: true }
但是打开 --harmony
开关后,问题出现了:
node -v
# OUTPUT:
# v6.9.1
node --harmony foo.js
# OUTPUT:
# foo invoked
# undefined
# [ERROR] Generator is already running
可以看到,差异有二:
next()
方法没有返回值;
生成函数常与co()
模块配合使用(本例中没有体现),此时就会出现报错:TypeError: Iterator result undefined is not an object
溢出执行
next()
方法会导出错误,即:Generator is already running
对于借助生成函数编写同步风格程序的设计来说,这种差异具有相当的破坏性。
版本比对
我们对比了一下 Node.js 版本:
Version | --harmony | 测试结果 |
---|---|---|
* | closed | normal |
6.4.0 | open | normal |
^6.5.0 | open | EXCEPTION |
7.0.0 | open | normal |
也就是说,这个问题只有在 6.5.0(含)以上,7.0.0(不含)以下版本的和谐模式中,才会出现。
深入剖析
对比一下两个版本下 V8 引擎的 harmony 特性,不知是否可以发现端倪?
# Here -- tells command grep the next parameters are not options.
node --v8-options | grep -- --harmony
# OUTPUT under node v6.5.0
--harmony (enable all completed harmony features)
--harmony_shipping (enable all shipped harmony features)
--harmony_array_prototype_values (enable "harmony Array.prototype.values" (in progress))
--harmony_object_observe (enable "harmony Object.observe" (in progress))
--harmony_function_sent (enable "harmony function.sent" (in progress))
--harmony_sharedarraybuffer (enable "harmony sharedarraybuffer" (in progress))
--harmony_simd (enable "harmony simd" (in progress))
--harmony_do_expressions (enable "harmony do-expressions" (in progress))
--harmony_regexp_property (enable "harmony unicode regexp property classes" (in progress))
--harmony_string_padding (enable "harmony String-padding methods" (in progress))
--harmony_regexp_lookbehind (enable "harmony regexp lookbehind")
--harmony_tailcalls (enable "harmony tail calls")
--harmony_object_values_entries (enable "harmony Object.values / Object.entries")
--harmony_object_own_property_descriptors (enable "harmony Object.getOwnPropertyDescriptors()")
--harmony_exponentiation_operator (enable "harmony exponentiation operator `**`")
--harmony_function_name (enable "harmony Function name inference")
--harmony_instanceof (enable "harmony instanceof support")
--harmony_iterator_close (enable "harmony iterator finalization")
--harmony_unicode_regexps (enable "harmony unicode regexps")
--harmony_regexp_exec (enable "harmony RegExp exec override behavior")
--harmony_sloppy (enable "harmony features in sloppy mode")
--harmony_sloppy_let (enable "harmony let in sloppy mode")
--harmony_sloppy_function (enable "harmony sloppy function block scoping")
--harmony_regexp_subclass (enable "harmony regexp subclassing")
--harmony_restrictive_declarations (enable "harmony limitations on sloppy mode function declarations")
--harmony_species (enable "harmony Symbol.species")
--harmony_instanceof_opt (optimize ES6 instanceof support)
# OUTPUT under node v6.4.0
--harmony (enable all completed harmony features)
--harmony_shipping (enable all shipped harmony features)
--harmony_object_observe (enable "harmony Object.observe" (in progress))
--harmony_modules (enable "harmony modules" (in progress))
--harmony_function_sent (enable "harmony function.sent" (in progress))
--harmony_sharedarraybuffer (enable "harmony sharedarraybuffer" (in progress))
--harmony_simd (enable "harmony simd" (in progress))
--harmony_do_expressions (enable "harmony do-expressions" (in progress))
--harmony_iterator_close (enable "harmony iterator finalization" (in progress))
--harmony_tailcalls (enable "harmony tail calls" (in progress))
--harmony_object_values_entries (enable "harmony Object.values / Object.entries" (in progress))
--harmony_object_own_property_descriptors (enable "harmony Object.getOwnPropertyDescriptors()" (in progress))
--harmony_regexp_property (enable "harmony unicode regexp property classes" (in progress))
--harmony_function_name (enable "harmony Function name inference")
--harmony_regexp_lookbehind (enable "harmony regexp lookbehind")
--harmony_species (enable "harmony Symbol.species")
--harmony_instanceof (enable "harmony instanceof support")
--harmony_default_parameters (enable "harmony default parameters")
--harmony_destructuring_assignment (enable "harmony destructuring assignment")
--harmony_destructuring_bind (enable "harmony destructuring bind")
--harmony_tostring (enable "harmony toString")
--harmony_regexps (enable "harmony regular expression extensions")
--harmony_unicode_regexps (enable "harmony unicode regexps")
--harmony_sloppy (enable "harmony features in sloppy mode")
--harmony_sloppy_let (enable "harmony let in sloppy mode")
--harmony_sloppy_function (enable "harmony sloppy function block scoping")
--harmony_proxies (enable "harmony proxies")
--harmony_reflect (enable "harmony Reflect API")
--harmony_regexp_subclass (enable "harmony regexp subclassing")