我想对C++本机函数进行异步调用,但有一些问题:当我在异步块中调用本机函数时(确切地说是这样),它会阻塞UI线程,而不进行异步调用。我想将回调传递给C++函数并调用它。如何传递函数对象?
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::value
有is_function_object
和is_function
方法,因此,我可能有机会将值转换为C++函数对象。但我该怎么做呢?
<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>
发布于 2022-09-30 05:50:35
好吧,这里有几种可能性:如果传递了一个函数或函数对象,我们可以使用callback.call()
,或者只返回像对象一样的承诺。示例:
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();
}
这就是如何调用回调函数。但是,我们可以简单地返回像对象一样的承诺(定义的这里):
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
并等待其结果。
https://stackoverflow.com/questions/73893180
复制相似问题