# Working with a JS `Promise` and a Rust `Future` Many APIs on the web work with a `Promise`, such as an `async` function in JS. Naturally you'll probably want to interoperate with them from Rust! To do that you can use the `wasm-bindgen-futures` crate as well as Rust `async` functions. The first thing you might encounter is the need for working with a `Promise`. For this you'll want to use [`js_sys::Promise`]. Once you've got one of those values you can convert that value to `wasm_bindgen_futures::JsFuture`. This type implements the `std::future::Future` trait which allows naturally using it in an `async` function. For example: [`js_sys::Promise`]: https://docs.rs/js-sys/*/js_sys/struct.Promise.html ```rust async fn get_from_js() -> Result { let promise = js_sys::Promise::resolved(&42.into()); let result = wasm_bindgen_futures::JsFuture::from(promise).await?; Ok(result) } ``` Here we can see how converting a `Promise` to Rust creates a `impl Future>`. This corresponds to `then` and `catch` in JS where a successful promise becomes `Ok` and an erroneous promise becomes `Err`. Next up you'll probably want to export a Rust function to JS that returns a promise. To do this you can use an `async` function and `#[wasm_bindgen]`: ```rust #[wasm_bindgen] pub async fn foo() { // ... } ``` When invoked from JS the `foo` function here will return a `Promise`, so you can import this as: ```js import { foo } from "my-module"; async function shim() { const result = await foo(); // ... } ``` ## Return values of `async fn` When using an `async fn` in Rust and exporting it to JS there's some restrictions on the return type. The return value of an exported Rust function will eventually become `Result` where `Ok` turns into a successfully resolved promise and `Err` is equivalent to throwing an exception. The following types are supported as return types from an `async fn`: * `()` - turns into a successful `undefined` in JS * `T: Into` - turns into a successful JS value * `Result<(), E: Into>` - if `Ok(())` turns into a successful `undefined` and otherwise turns into a failed promise with `E` converted to a JS value * `Result, E: Into>` - like the previous case except both data payloads are converted into a `JsValue`. Note that many types implement being converted into a `JsValue`, such as all imported types via `#[wasm_bindgen]` (aka those in `js-sys` or `web-sys`), primitives like `u32`, and all exported `#[wasm_bindgen]` types. In general, you should be able to write code without having too many explicit conversions, and the macro should take care of the rest! ## Using `wasm-bindgen-futures` The `wasm-bindgen-futures` crate bridges the gap between JavaScript `Promise`s and Rust `Future`s. Its `JsFuture` type provides conversion from a JavaScript `Promise` into a Rust `Future`, and its `future_to_promise` function converts a Rust `Future` into a JavaScript `Promise` and schedules it to be driven to completion. Learn more: * [`wasm_bindgen_futures` on crates.io][crate] * [`wasm-bindgen-futures` API documentation and example usage][docs] [crate]: https://crates.io/crates/wasm-bindgen-futures [docs]: https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen_futures/ ## Compatibility with versions of `Future` The current crate on crates.io, `wasm-bindgen-futures 0.4.*`, supports `std::future::Future` and `async`/`await` in Rust. This typically requires Rust 1.39.0+ (as of this writing on 2019-09-05 it's the nightly channel of Rust). If you're using the `Future` trait from the `futures` `0.1.*` crate then you'll want to use the `0.3.*` track of `wasm-bindgen-futures` on crates.io.