背景:v8支持yield(旧消息,我知道),这很好地取消了javascript代码中的回调,例如node.js中使用的内容(请参阅{{3} })
问题:由于javascript协同例程可以调用C ++代码(通过模块),调用的C ++如何执行yield操作?举例说明:
// javascript
function* values()
{
yield 27;
mycppmodule.someFunction();
}
// c++
mycppmodule::someFunction()
{
__somehow_yield( 28 ); // how can we make this happen?
}
// user of the code above
var o = values();
o.next(); // returns 27 - came from javascript above
o.next(); // returns 28 - came from c++ above, which is invoked by js
我怀疑答案是在V8 API中的某个地方(https://wingolog.org/archives/2013/05/08/generators-in-v8),但我的搜索没有产生(双关语)任何结果......
答案 0 :(得分:2)
您的mycppmodule.someFunction();
无法从生成器函数values()
返回的生成器中获取值,即使它是用JavaScript编写的。如果你想在C ++中做一些与JavaScript中的其他代码一样的东西,那么你必须确保它首先在JavaScript中起作用。
如果你想使用基于生成器的协同程序(比如co
模块或Bluebirds的coroutine
),那么情况会有所不同 - 任何协同程序只会返回一个承诺以及你从生成器实际上是一个你希望在生成器的下一次运行中解析并注入的承诺,但在这里似乎并非如此。
有人说过,首先要确保你的想法可以用JsvaScript实现,我认为这个:
function* values() {
yield 27;
someFunction();
}
let someFunction = // fill the blanks
var o = values();
o.next(); // returns 27 - came from generator
o.next(); // returns 28 - came from someFunction()
如果不将values()
生成器函数更改为:,则无法实现
function* values() {
yield 27;
let gen = someFunction();
yield gen.next();
}
或:
function* values() {
yield 27;
yield* someFunction();
}
如果您可以更改原始values()
功能,请继续阅读。
现在,生成器函数所做的就是返回一个生成器的对象。该生成器包含.next()
,.throw()
和.return()
等方法。如果你在C ++中创建一个具有正确接口的对象,那么你可以在JavaScript中使用它作为yield*
等关键字的生成器,但我必须对其进行测试以确保它。
参见文档: