Reputation: 99
Have a WASM program that takes ~12 seconds to run on my machine. To keep the user on the site, it'd be nice to indicate that the program is making progress. I inserted some calls using EM_ASM_(...)
in the C++ WASM code to a JS function that's equivalent to:
function updateStatus(number) {
console.log("status: ", number);
document.getElementById("status").innerHTML = "Status: " + number;
}
While the console gets live updates, the "status" DOM element is not updated until the WASM code finishes.
I tried adding sleep(1)
after the updateStatus()
call in the C++ code, but that didn't lead to an update.
Upvotes: 0
Views: 146
Reputation: 99
The following C code seems to work, though there's a separate issue noted below:
EM_JS(void, updateStatus, (int number), {
Asyncify.handleAsync(async() => {
await Promise.resolve()
.then(function() {
console.log("status: ", number);
document.getElementById("status").innerHTML = "Status: " + number;
});
await new Promise(r => setTimeout(r, 50));
});
});
void myWASM() {
...
for(int number = 0; number < MAX; number++) {
...
updateStatus(number);
...
}
...
printf("done with myWASM()");
}
The updates didn't appear live without the Promise/setTimeout
call at the end, but this may be a general feature of DOM updates?
An oddity is that the cwrap
'd to myWASM()
returns to the JS caller before "done with myWASM()" executes. Seems like the myWASM()
call is now asyncronous? Going to post a separate question on this.
Thanks to @sbc100 for suggesting ASYNCIFY.
Upvotes: 0
Reputation: 70122
The JavaScript runtime yields to WebAssembly, which explains why the UI is not updated. To achieve what you are after you need to run your code in a Web Worker.
Upvotes: 1