使用C++20中的协程实现一个WASM函数,此函数可以实现js中setTimeout的效果
实现方案
- 定义一个Awaitable协议的结构实现sleep逻辑
- 声明一个返回值为val的函数,并且使用co_return进行返回,因为val这个变量在emscripte中已经有promise_type的声明,所以无需进行额外处理
- 使用embind导出函数并在html中调用
实现代码
struct Sleep {
int _ms;
std::coroutine_handle<> _handle;
Sleep(int val) : _ms(val) {}
bool await_ready() { return false; }
void await_suspend(std::coroutine_handle<> handle) {
_handle = handle;
emscripten_async_call(
[](void* val) {
auto obj = (Sleep*)val;
obj->_handle.resume();
},
this, _ms);
}
void await_resume() {}
};
val sleep2(int ms) {
co_await Sleep(ms);
co_return val::null();
}
EMSCRIPTEN_BINDINGS(module) {
function("sleep2", sleep2);
}
调用示例
<html>
<script>
var Module = {
onRuntimeInitialized: async () => {
try {
console.log('sleep2 start')
Module.sleep2(1000)
await Module.sleep2(1000)
console.log('sleep2 end')
} catch (e) {
console.error(e)
}
}
};
</script>
<script src="./build/main.js"></script>
</html>