背景:v8 支持 Yield(我知道是旧消息),这对于消除 JavaScript 代码中的回调(例如在 Node.js 中使用的回调)非常有用(请参阅 https://wingolog.org/archives/2013/05/08/generators-in-v8 )
问题:既然 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://v8docs.nodesource.com/node-7.4/ ) 中的某个地方,但我的搜索没有产生(双关语)任何结果...
最佳答案
您的 mycppmodule.someFunction();
无法从生成器函数 values()
返回的生成器中生成值,即使它是用 JavaScript 编写的。如果您想在 C++ 中做一些像 JavaScript 中其他代码一样工作的事情,那么您必须首先确保它可以在 JavaScript 中工作。
如果您想使用基于生成器的协程(例如使用 co
模块或 Bluebirds 的 coroutine
),那么情况会有点不同 - 任何协程都只返回一个 promise 从生成器中生成的实际上是一个 promise ,您希望在生成器的下一次运行中解析并注入(inject)该 promise ,但这里的情况似乎并非如此。
话虽如此,首先确保您的想法可以在 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++ 中创建一个具有正确接口(interface)的对象,那么您也许可以将其用作 JavaScript 中的生成器,并使用 yield*
等关键字,但我必须对其进行测试以确保这一点。
查看文档:
关于javascript - node.js:如何从 C++ 模块中产生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43629431/