Is it possible to run WebAssembly code async?
Asked Answered
E

3

17

I have written a C function that I am able to execute from Angular/TypeScript/JavaScript using WebAssembly:

testWebAssembly() {
    Module.ccall("aCFunction", null, [], []); // takes a few seconds to finish
}

This function does some heavy mathematical calculations and needs a few seconds to finish. It is fired when a user clicks a button:

<button (click)="testWebAssembly()">Launch C function</button>

Is it possible to execute the function so that it does not block the UI of the web application?

I tried setTimeOut/async/Promise, but I don't seem to be able to make it work.

Thank you!

Eleni answered 7/6, 2018 at 1:11 Comment(1)
have you considered webworkers?Schoof
R
17

WebAssembly and JavaScript share the same execution thread, i.e. when you execute WebAssembly from within JavaScript, your JavaScript code halts, and vice-versa. In that respect it's just like executing any other native (i.e, browser-supplied) APIs from your JavaScript code.

One option you do have is to run your WebAssembly in a WebWorker, using postMessage to send messages to your wasm code that executed in a different thread. There's a great example here, that renders a fractal using WebWorkers:

https://www.reddit.com/r/rust/comments/8hdq5r/a_rust_javascript_web_workers_fractal_renderer/

In the future WebAssembly will likely have its own support for threading:

https://github.com/WebAssembly/threads

Rodrich answered 7/6, 2018 at 6:47 Comment(2)
Note that even with the threads proposal you cannot actually create threads in Wasm itself, but have to do so with workers on the JS side.Raver
Do you know a good source that explains web workers for Angular/TypeScript? I didn’t know about web workers and haven‘t used them yet.Eleni
R
7

Asynchronous execution alone won't take it off the main thread. What you actually mean is executing it concurrently. The only way to achieve that on the Web is by using worker threads.

Raver answered 7/6, 2018 at 6:40 Comment(0)
P
0

If you can split up the work into smaller chunks, you can return control to the browser to do his stuff after each chunk. To let your function continue when the browser has completed, you can register the next chunk using async just before returning from your function.

I haven't tried this in Rust myself yet, but this is how it's usually done in the browser to not make it appear hanging.

Propeller answered 11/1 at 15:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.