Skip to main content

web_task/
lib.rs

1//! This crate is a modern alternative to `web-bindgen-futures` built around `async-task`.
2//!
3//! # Pros & Cons
4//!
5//! **Pros:**
6//! + Provides both [`spawn`] (for `Send` futures) and [`spawn_local`] (for `!Send` futures).
7//! + [`spawn`] and [`spawn_local`] return [`Task<T>`](async_task::Task) futures, which resolve to return values.
8//! + It's possible to cancel futures using task handles.
9//! + Non-send futures (which are common on web) can have send task-handles.
10//!
11//! **Cons:**
12//! + Some older browser versions are not supported.
13//!
14//! # Runtime Support
15//!
16//! Enabling the `+atomics` nightly target feature automatically switches the
17//! crate to a multithreaded runtime, which may have different performance charictaristics.
18
19#![no_std]
20#![cfg_attr(
21    target_feature = "atomics",
22    feature(thread_local, stdarch_wasm_atomic_wait)
23)]
24#![deny(missing_docs)]
25
26extern crate alloc;
27
28use async_task::Task;
29
30mod queue;
31
32mod runtime {
33    use cfg_if::cfg_if;
34
35    cfg_if! {
36        if #[cfg(target_feature = "atomics")] {
37            mod multithread;
38            pub(crate) use multithread::*;
39
40        } else {
41            mod singlethread;
42            pub(crate) use singlethread::*;
43         }
44    }
45}
46
47/// Spawns a [`Future<Output = T>`](core::future::Future) that can execute on
48/// any thread; returns a [`Task`].
49///
50/// The future will be polled to completion in the background. Awaiting the
51/// returned task has no effect when the future is polled. Dropping the task
52/// will cancel the future, unless you call [`Task::detach()`] first.
53#[inline]
54pub fn spawn<F>(future: F) -> Task<F::Output>
55where
56    F: Future + Send + 'static,
57    F::Output: Send + 'static,
58{
59    runtime::Job::spawn(future)
60}
61
62/// Spawns a [`Future<Output = T>`](core::future::Future) that executes on the
63/// current thread; returns a [`Task`].
64///
65/// The future will be polled to completion in the background. Awaiting the
66/// returned task has no effect when the future is polled. Dropping the task
67/// will cancel the future, unless you call [`Task::detach()`] first.
68#[inline]
69pub fn spawn_local<F>(future: F) -> Task<F::Output>
70where
71    F: Future + 'static,
72    F::Output: 'static,
73{
74    runtime::Job::spawn_local(future)
75}