gpt4 book ai didi

javascript - 在 Spidermonkey JS 引擎中异步调用回调函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:48:22 24 4
gpt4 key购买 nike

使用 Spidermonkey v27:

“保留”然后从 C++ 异步调用临时 JS 函数的正确方法是什么?

JS代码:

myFunction(function(){
console.log("The function works");
});

C++代码:

bool js_myFunction(JSContext* cx, uint32_t argc, jsval* vp)
{
if (argc == 1)
{
implement_async_function(cx, vp);
JS_SET_RVAL(cx, vp, JSVAL_NULL);
return true;
}
return false;
}

static JSContext* savedContext;
static jsval* savedVal;
void implement_async_function(JSContext* cx, jsval* vp)
{
// if the function is called immediately, everything is okay!
jsval retVal;
JS_CallFunctionValue(cx, nullptr, *vp, 0, nullptr, &retVal);
// "The function works"

// if some work has to be done before calling the callback...
savedContext = cx;
savedVal = vp;
start_async_process();
}

void async_process_complete()
{
jsval retVal;
JS_CallFunctionValue(savedContext, nullptr, *savedVal, 0, nullptr, &retVal);
// "<no filename="filename">:0:true is not a function"
// or else it crashes...
}

void alternate_implement_async_function(JSContext* cx, jsval* vp)
{
// also tried this:
savedContext = cx;
savedVal = vp;
JS_AddValueRoot(savedContext, savedVal);
start_async_process();

// and this:
savedContext = cx;
savedVal = new jsval(*vp);
JS_AddValueRoot(savedContext, savedVal);
start_async_process();

// and using JS::RootedValue

// and using JS::Heap<JS::Value>

// and using the global context instead of the saved context
}

我已经通读了 SpiderMonkey 的文档:

https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_Reference/JS::Value

https://developer.mozilla.org/en-US/docs/SpiderMonkey/GC_Rooting_Guide

https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_AddRoot

https://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_CallFunctionValue

并查看了这篇 StackOverflow 帖子 Spidermonkey and Garbage Collection

甚至尝试让 JS 回调函数成为一个永远不应该被垃圾回收的全局函数。 (虽然这不是我想要的。)

最佳答案

您没有提到您的程序在尝试异步调用该函数时的行为,但我认为在尝试调用该函数时它会出现段错误,因为 GC 可能已经移动了它。您需要一种方法来存储函数对象(它不是您代码中的值)。 JS::Rooted在这种情况下是 Not Acceptable ,因为堆栈生根期望 gc 事物以后进先出顺序生根。因此,您需要将其存储在 JS::Heap<JSObject*> 中。处理。 JS::Heap handle 期望存在于堆上而不是栈上(可能在列表或树结构中)。警告 JS::Heap handles 是它们需要由 GC 跟踪,以便可以重新定位底层对象并更新您的句柄。 this question 中讨论了跟踪.

假设您的对象现在已正确存储和跟踪,您应该可以随时调用它而不会出现任何问题。

关于javascript - 在 Spidermonkey JS 引擎中异步调用回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22698268/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com