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.