Quantcast
Channel: ReScript Forum - Latest posts
Viewing all articles
Browse latest Browse all 2592

Promise helper name

$
0
0

definitely sleep. what i would ask you to do however is make it cancelable:

from one of our internal projects:

/***
Async helpers.

Utilities for timeouts, cancelable sleeps, and racing promises against a timeout.
Useful for bounding async work and composing promise-based control flow.
*/

/**
A promise that can be canceled.

- `promise`: resolves to `Some(value)` on success, or `None` if canceled/timeout fires first
- `cancel`: immediately resolves `promise` with `None`
*/
type cancelablePromise<'a> = {
  promise: promise<option<'a>>,
  // Immediately resolves the promise with None
  cancel: unit => unit,
}

/**
Create a cancelable sleep.

- `ms`: delay in milliseconds
- Returns a `{promise, cancel}` where:
  - `promise` resolves to `Some(())` after `ms`
  - calling `cancel()` resolves it early with `None`
*/
let sleepCancelable = (~ms: int): cancelablePromise<unit> => {
  let resolveMut = ref(_ => ())
  let timeoutMut = ref(None)

  let p = Promise.make((resolve, _) => {
    resolveMut := resolve

    let cb = () => {
      resolveMut.contents(Some())
      resolveMut := (_ => ())
      timeoutMut := None
    }
    timeoutMut := Some(setTimeout(cb, ms))
  })

  let cancel = () => {
    switch timeoutMut.contents {
    | Some(id) =>
      clearTimeout(id)
      resolveMut.contents(None)
      resolveMut := (_ => ())
      timeoutMut := None
    | None => ()
    }
  }

  {promise: p, cancel}
}

/**
Sleep for `ms` milliseconds.

Resolves when the delay elapses. Non-cancelable convenience wrapper around `sleepCancelable`.
*/
let sleep = (~ms) => sleepCancelable(~ms).promise->Promise.thenResolve(_ => ())

anyway, sleep has been the name for this type of functionality for decades (takes me back to the good old days of win32 api), and if you put it under Promise, it’s obvious it’s async.


Viewing all articles
Browse latest Browse all 2592

Trending Articles