首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将JS函数作为函数参数传递给C++

将JS函数作为函数参数传递给C++
EN

Stack Overflow用户
提问于 2022-09-29 09:23:19
回答 1查看 40关注 0票数 0

我想对C++本机函数进行异步调用,但有一些问题:当我在异步块中调用本机函数时(确切地说是这样),它会阻塞UI线程,而不进行异步调用。我想将回调传递给C++函数并调用它。如何传递函数对象?

代码语言:javascript
运行
复制
class frame : public sciter::window {
public:
    frame() : window(SW_TITLEBAR | SW_RESIZEABLE | SW_CONTROLS | SW_MAIN | SW_ENABLE_DEBUG) {}

void assertion(const std::string& val)
{
    stream << std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count() 
        << ' '
        << val 
        << '\n';
    stream.flush();
}

void asyncFunction(::sciter::value callback)
{
    std::thread{ [callback]() 
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // if I use it in same thread, it blocks UI thread and no async call is made
        // call callback function
    } }.detach();
}

SOM_PASSPORT_BEGIN(frame)
    SOM_FUNCS(
        SOM_FUNC(assertion),
        SOM_FUNC(asyncFunction)
    )
SOM_PASSPORT_END

private:
    std::ofstream stream{ "log.txt" };
};

在这个实现中,我使用另一个线程来创建一个逻辑。但是,如果我想返回值(或者通知,该调用已经完成),我需要触发事件(我不想做的事情,因为逻辑将在整个代码上传播)或调用某种回调。sciter::valueis_function_objectis_function方法,因此,我可能有机会将值转换为C++函数对象。但我该怎么做呢?

代码语言:javascript
运行
复制
<html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <button #test>Assert</button>
        <script>
            function sleep(time) {
                return new Promise(resolve => {
                    Window.this.frame.asyncFunction(function (result)
                    {
                        Window.this.frame.assertion(result);
                        resolve(result);
                    }); // resolve(Window.this.frame.asyncFunction()) blocks code execution until asyncFunction returns
            });
            }

            async function answer() {
                Window.this.frame.assertion("sleep start");
                await sleep(5000);
                Window.this.frame.assertion("sleep end");
                return 50;
            }

            document.$("button#test").onclick = function () {
                var p = answer();
                p.then(result => { Window.this.frame.assertion("Ended: " + result) });
                Window.this.frame.assertion("go next");
            }
        </script>
    </body>
</html>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-30 05:50:35

好吧,这里有几种可能性:如果传递了一个函数或函数对象,我们可以使用callback.call(),或者只返回像对象一样的承诺。示例:

代码语言:javascript
运行
复制
void asyncFunction(::sciter::value callback)
{
    std::thread{ [callback]() 
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(5000));
        sciter::value result = sciter::value(42);
        callback.call(result); // invoke the callback function.
    } }.detach();
}

这就是如何调用回调函数。但是,我们可以简单地返回像对象一样的承诺(定义的这里):

代码语言:javascript
运行
复制
 sciter::value nativeAsyncFunction(int milliseconds)
  {
    sciter::om::hasset<NativePromise> promise = new NativePromise();

    std::thread([=]() {
       std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
       promise->resolve(42);
      }).detach();

    return sciter::value::wrap_asset(promise);
  }

在这种情况下,我们不需要创建像sleep这样的附加函数,我们只需在answer中调用nativeAsyncFunction并等待其结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73893180

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档