Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Futures 0.3 + async/await syntax #1105

Closed
liamcurry opened this issue Dec 11, 2018 · 13 comments
Closed

Futures 0.3 + async/await syntax #1105

liamcurry opened this issue Dec 11, 2018 · 13 comments

Comments

@liamcurry
Copy link
Contributor

Hi again! I have a two-part question here.

First, I'm trying to work out how SPA routing could work with wasm-bindgen, where navigating to a new route requires fetching data from an API. Based on this conversation it sounds like the fetch request would need to be called by JS at some point, but I'm not sure what that should look like.

Is this possible with just one #[wasm_bindgen(start)] function, or is more JS required?

Second, I would like to use the new async/await! syntax if possible but I'm running into compiler errors with my local experiments. Here's an example:

#![feature(async_await, futures_api, await_macro, pin)]

use futures::compat::Compat;
use js_sys::Promise;
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::future_to_promise;

async fn test() -> Result<JsValue, JsValue> {
    Ok(JsValue::from(1))
}

#[wasm_bindgen]
pub fn run() -> Promise {
    future_to_promise(Compat::new(test()))
}

I see errors like this:

error[E0277]: the trait bound `std::future::GenFuture<[static generator@web_client\src\lib.rs:87:45: 89:2 {}]>: std::pin::Unpin` is not satisfied in `impl core::future:
:future::Future`
  --> web_client\src\lib.rs:97:5
   |
97 |     future_to_promise(fut)
   |     ^^^^^^^^^^^^^^^^^ within `impl core::future::future::Future`, the trait `std::pin::Unpin` is not implemented for `std::future::GenFuture<[static generator@web_
client\src\lib.rs:87:45: 89:2 {}]>`
   |
   = help: the following implementations were found:
             <std::future::GenFuture<T> as std::pin::Unpin>
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because of the requirements on the impl of `futures::future::Future` for `futures_util::compat::compat03as01::Compat<impl core::future::future::Futu
re>`
   = note: required by `wasm_bindgen_futures::future_to_promise`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: Could not compile `web_client`.

I'm using futures-preview = { version = "0.3.0-alpha.10", features = ["compat"] } and trying to convert to a 0.1 Future that wasm-bindgen-futures can use and convert to a Promise. I don't have a full grasp on futures/async/await in Rust so there's a good chance I'm doing something obviously wrong.

Bonus question: has the futures 0.3 API stabilized enough that it could be supported? 😃

Thanks for your time!

@alexcrichton
Copy link
Contributor

For the first part I think in theory you can use the conversions between JS promises and Rust futures to define everything in Rust, but you may run into snags to work through!

For the second that looks related to the futures 0.1 and 0.3 shims perhaps, maybe a Box is needed?

For the last part, we're waiting on 0.3 to run on stable Rust, but we'll update to that as soon as we can! In the meantime though having a wasm-bindgen-futures-0.3 crate or something like that is totally plausible to do!

@corbinu
Copy link
Contributor

corbinu commented Dec 29, 2018

Would anybody be willing to help me I am trying to create a PR for a version of the futures crate that would support futures0.3/async but running into some struggles. Would really like to be able to offer them even if is only for those using nightly for now.

@Pauan
Copy link
Contributor

Pauan commented Dec 29, 2018

@corbinu Sure, I have a lot of experience with Futures (having ported my Signals crate from 0.1 to 0.3), so I can help.

Personally, I think a nightly feature flag (or similar) would be the way to go, but it's up to @alexcrichton

@corbinu
Copy link
Contributor

corbinu commented Dec 30, 2018

@Pauan Sure let me create a fork and add you. Thanks I really want to release a few example crates using WASM that work both in Rust and Node.

@kanru
Copy link

kanru commented Mar 17, 2019

#[wasm_bindgen]
pub fn run() -> Promise {
    future_to_promise(Compat::new(test()))
}

Bumped into this issue today. The solution is to pin the GenFuture like this

future_to_promise(Compat::new(test().boxed()))

@liamcurry liamcurry changed the title Routing with Futures + async/await syntax? Futures 0.3 + async/await syntax Mar 17, 2019
@steveklabnik
Copy link

Futures have stabilized in nightly! 🎊

@Pauan
Copy link
Contributor

Pauan commented Apr 30, 2019

Right, but we have to wait until it actually lands in the Stable compiler before we can use it. That'll probably be sometime in July.

@alexcrichton
Copy link
Contributor

Thanks for the ping on this @steveklabnik, and I actually personally think we should go ahead and get this done. This would be behind an off-by-default feature gate to ensure that we don't regress current users of the wasm-bindgen-futures crate, but users using an appropriate compiler could enable the feature and get access to async/await!

@Pauan would you be ok with that strategy?

@Pauan
Copy link
Contributor

Pauan commented Apr 30, 2019

@alexcrichton Yeah, that sounds great to me.

@alexcrichton
Copy link
Contributor

Support for this has been implemented in #1507!

@Pauan
Copy link
Contributor

Pauan commented May 6, 2019

To use Futures 0.3, first enable the futures_0_3 feature:

[dependencies]
wasm-bindgen-futures = { version = "0.3.20", features = ["futures_0_3"] }

Then import and use the futures_0_3 module:

use wasm_bindgen_futures::futures_0_3::{JsFuture, future_to_promise, spawn_local};

(You also have to wait for the new version of wasm-bindgen-futures to be released)

@steveklabnik
Copy link

Any idea on when that release may happen? I'd like to give it a try!

@alexcrichton
Copy link
Contributor

I've posted a new release at #1536

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants