I have the following WASM code with the asynchronous function request_data
that performs an asynchronous call to an arbitrary API and logs the resolved Promise to the console. To check for orchestration, I am logging before and after I execute this function. Naturally, when I am not specifying to wait for the asynchronous function, its output will be logged after my surrounding logs:
use wasm_bindgen::prelude::*;
#[wasm_bindgen(inline_js = "export async function request_data() { console.log(await <some_async_call>) }")]
extern {
pub async fn request_data();
}
#[wasm_bindgen(inline_js = "export function log(text) { console.log(text) }")]
extern {
pub fn log(text: &str);
}
#[wasm_bindgen]
pub fn main() {
log("Before");
request_data();
log("After");
}
When I run function main
, I am getting the following output to the console:
Before
After
<async call result data>
What I want to achieve is to let the main
function wait until the Future resolves, before it is logging "After"
. I tried the following, but it just endlessly wait for the Future to resolve:
use wasm_bindgen::prelude::*;
use futures::executor::*;
#[wasm_bindgen(inline_js = "export async function request_data() { console.log(await <some_async_call>) }")]
extern {
pub async fn request_data();
}
#[wasm_bindgen(inline_js = "export function log(text) { console.log(text) }")]
extern {
pub fn log(text: &str);
}
#[wasm_bindgen]
pub fn main() {
log("Before");
block_on(request_data());
log("After");
}
This just leads to this output
Before
So my question is, how I can orchestrate the main
function to get the following output:
Before
<async call result data>
After
Make the calling function async too:
#[wasm_bindgen]
pub async fn main() {
log("Before");
request_data().await;
log("After");
}
When this function is exported to JavaScript, it will become a function returning a Promise
, just like a JS async function. That's all you need to do, usually.
From the perspective of Rust async, the browser provides an already-existing, single-threaded async executor. You should not use any other async executor within it. The wasm-bindgen-futures
library provides API for explicitly working with promises and futures if you need to.