Skip to content

Cancelable Timeouts/Intervals #254

Closed
@simbleau

Description

@simbleau

Summary

Synchronously, we get an ID from a Timeout::new().forget() or Interval::new().forget().
Is there a reason we have to consume the object and return a u64 ID? I don't think so.

I believe a better solution would be to have an inner field on the object, id: Option<u64> which holds such an ID if it was forgot()'ed or submitted async.

And hence, then we could implement cancel() after it has been sent as a hook to web_sys::cancel_timeout_with_handle(&self: &Window, id: u64)

Motivation

The motivation is that (in my opinion) it's not straightforward to cancel a Timeout or Interval for the average user, and this is not ergonomic as a result.

Detailed Explanation

TLDR:

pub struct Timeout<F: FnOnce> { 
    id: Option<u64>,
    f: F,
}

impl<F: FnOnce> Timeout<F> {
    pub fn new(f: F) -> Self { ... }
    pub fn forget(&mut self) {
        let id = web_sys::submit_timeout.... // Whatever it is currently
        self.id = Some(id)
    }

    pub fn cancel(self) { 
        if let Some(id) = self.id {
            self.id = None;
            web_sys::window().map(|w| w.cancel_timeout_with_handle(id)).expect_throw("No window")
        }
    }

    pub fn id(&self) -> Option<u64> { 
        self.id
    }
}

Drawbacks, Rationale, and Alternatives

It would be a breaking change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsRelated to documentation and the guide

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions