Deferral utilities
inTimeout#
inTimeout(ms) returns a lazy promise that fires with a value of type void in a setTimeout callback. If unsubscribed before it fires, calls clearTimeout.
For example, to sleep for 1 second in the middle of a generator function, you would
yield* inTimeout(1000);To make a lazy promise time out, you can do
race([
lazyPromise,
// Or `.map(() => new ErrorBox("timeout"))` (see "Type-safe errors").
inTimeout(ms).map(() => {
throw new Error(`Timed out.`);
}),
]);inMicrotask#
inMicrotask() returns a lazy promise that fires with a value of type void in a queueMicrotask callback. If the lazy promise is unsubscribed before firing, the callback cannot be un-scheduled, but becomes a no-op.
inAnimationFrame#
inAnimationFrame() returns a lazy promise that fires with a value of type DOMHighResTimeStamp in a requestAnimationFrame callback. If unsubscribed before it fires, calls cancelAnimationFrame.
Not available in Node.
inIdleCallback#
inIdleCallback({ timeout }) returns a lazy promise that fires with a value of type IdleDeadline in a requestIdleCallback callback, passing on the options object. If unsubscribed before it fires, calls cancelIdleCallback.
Not available in Node, limited availability in browsers.
inImmediate#
inImmediate() returns a lazy promise that fires with a value of type void in a setImmediate callback. If unsubscribed before it fires, calls clearImmediate.
Not available in modern browsers.
inNextTick#
inNextTick() returns a lazy promise that fires with a value of type void in a process.nextTick callback. If the lazy promise is unsubscribed before firing, the callback cannot be un-scheduled, but becomes a no-op.
Not available in browsers.
inMessageChannel#
inMessageChannel() posts a message in a MessageChannel and resolves with a value of type void when it receives the message back, unless by then it has been unsubscribed. In Node, it keeps the process alive while messages are pending and unrefs the port once the queue is empty.
To keep the browser UI responsive during heavy synchronous work, you could do the following:
let deadline = 0;
const resetDeadline = () => {
deadline = performance.now() + 5;
};
const maybeYieldToEventLoop = defer(() => {
if (performance.now() < deadline) {
return;
}
return inMessageChannel().map(resetDeadline);
});
const longRunningTask = fromGen(function* () {
for (const item of items) {
// Do work...
yield* maybeYieldToEventLoop;
}
});inScheduled#
inScheduled({ priority }) returns a lazy promise that fires with a value of type void in a scheduler.postTask callback. If unsubscribed before it fires, cancels the task using an AbortSignal. Takes an options object with task priority (“user-visible” by default).
Limited availability in browsers.