Promise.delay (sleep) and Promise.timeout

Update: please go to https://discourse.wicg.io/t/promise-delay-sleep-and-promise-timeout/4644

Related Sleep function

await Promise.delay(2000)
// resolves after _at least_ 2000 ms, same as setTimeout
await Promise.timeout(fetchTaskPromise, 2000)
// rejects after 2000ms if fetchTaskPromise not resolved

Does anyone interested in this?

setTimeout isn't in the language, and other than Date, and the upcoming Temporal.now, there's no concept of a "clock", by design.

I think it'd be hugely useful, but I'm skeptical it'd be possible to specify.

there's no concept of a "clock", by design.

Hmm yes. But it possible to implement a clock by Promise + Date.now().

setTimeout isn't in the language

What about, if the host is providing a setTimeout, it should also extends Promise.delay and timeout? So we can refer to the setTimeout and still not specifying them in the spec.

Interesting, I try to impl a setTimeout by using only blocks in the ES spec.

async function myTimeout(time, callback) {
    const now = Date.now()
    while (true) {
        await Promise.resolve(0)
        if (now + time < Date.now()) return callback()
    }
}

And this won't work, it's blocking the main thread. I think I'm not master at event loops micro tasks etc. But is it even possible to do that? :thinking:

I think not without workers or requestAnimationFrame or setTimeout or setInterval, which also all aren't in the language.

Possible spec text:

Promise.delay(timeout):

This section is optional for the hosts that doesn't have a builtin "setTimeout" (close to the HTML semantics). If hosts decided to implement this, it's RS should be very close to the semantics in HTML if it is possible so developers won't be surprised.

Algorithm:

  1. If Type(timeout) is not "number", throw TypeError
  2. Let promise be new %Promise%
  3. Call(%setTimeout%, %globalThis%, [resolver function of promise, timeout)
  4. return promise

node’s setTimeout returns an object timer.

The only way this could be specified, i think, is by including setTimeout in 262 - we can’t just refer to the HTML spec. “Optional” still means non-web engines including non-node) can choose to implement it, and they shouldn’t have to read the HTML spec to do it.

Maybe, we can vaguely describe this function (since there is no clock in the es spec) and give suggested algorithm (not requirement), then suggest hosts to define their own version.

Perhaps it’s possible to Promise.delay in terms of clock semantics that are a suitable common foundation for describing setTimeout without specifying setTimeout. Promise.delay would also need a cancellation mechanism, which also means possibly hoisting cancellation tokens up.

This seems desirable, possible, and laden with dependencies.

Moved the discussion to WICG: https://discourse.wicg.io/t/promise-delay-sleep-and-promise-timeout/4644