diff --git a/crates/futures/src/queue.rs b/crates/futures/src/queue.rs index 9a78571cd845..edfd7f04d32b 100644 --- a/crates/futures/src/queue.rs +++ b/crates/futures/src/queue.rs @@ -4,6 +4,12 @@ use std::collections::VecDeque; use std::rc::Rc; use wasm_bindgen::prelude::*; +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(catch)] + fn queueMicrotask(closure: &Closure) -> Result<(), JsValue>; +} + struct QueueState { // The queue of Tasks which are to be run in order. In practice this is all the // synchronous work of futures, and each `Task` represents calling `poll` on @@ -48,10 +54,9 @@ impl Queue { // Schedule a task to run on the next tick pub(crate) fn schedule_task(&self, task: Rc) { self.state.tasks.borrow_mut().push_back(task); - // Note that we currently use a promise and a closure to do this, but - // eventually we should probably use something like `queueMicrotask`: - // https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/queueMicrotask - if !self.state.is_scheduled.replace(true) { + // Use queueMicrotask to execute as soon as possible. If it does not exist + // fall back to the promise resolution + if !self.state.is_scheduled.replace(true) && queueMicrotask(&self.closure).is_err() { let _ = self.promise.then(&self.closure); } }