timers
All the timing functions you need - for Deno and the browser.
Installation
Just import it directly from the https://deno.land/x/
registry
import {
delay,
setInterval,
setTimeout,
times,
} from "https://deno.land/x/timers@v0.2.0/mod.ts";
Features
long timeouts and intervals
With every function timers
exports, it is possible to have a timeout or
interval that is longer than 24.8 days (2^31-1 milliseconds).
If you need only this functionality,Ā timers
exports the functions
setTimeout
, setInterval
, clearTimeout
and clearInterval
.
They are almost completely compatible with the Web APIās functions, but it is not allowed to pass a string as function argument to one of them.
Important Note
You canāt use the native functions mixed with the functions exported by this
module! So, if you import setTimeout
, you should import clearTimeout
as
well, as the native function wonāt clear the timeout!
import {
clearInterval,
clearTimeout,
setInterval,
setTimeout,
} from "https://deno.land/x/timers@v0.2.0/mod.ts";
const timeout = setTimeout(() => {
console.log("in 30 days");
}, 1000 * 60 * 60 * 24 * 30);
const interval = setInterval(() => {
console.log("every 30 days");
}, 1000 * 60 * 60 * 24 * 30);
// Clear them
clearTimeout(timeout);
clearInterval(interval);
Tip
If you donāt want the native functions overwritten, setTimeout
and
setInterval
are exported as setLongTimeout
and setLongInterval
as well.
This also applies to clearTimeout
and clearInterval
. Also you can at any
time use globalThis.setTimeout
, which applies to the other functions as well
import {
clearLongInterval,
clearLongTimeout,
setLongInterval,
setLongTimeout,
} from "https://deno.land/x/timers@v0.2.0/mod.ts";
time strings
With each function expect setInterval
and setTimeout
, that timers
exports,
it is possible to use a time string as delay argument instead of the number of
milliseconds. For example:
import { every } from "https://deno.land/x/timers@v0.2.0/mod.ts";
every("1minute").do(() => {
console.log(new Date().toLocaleTimeString());
});
supported format
- ms, millisecond, milliseconds
- s, sec, secs, second, seconds
- m, min, mins, minute, minutes
- h, hour, hours
- d, day, days
Examples
2 days, 5 hours and 2 minutes
3sec, 2ms
5mins3secs
delay
timers
exports the function delay
. The API is like the
delay function from denoās std library,
but it returns an AbortablePromise
, so you can abort the promise with calling
abort()
on it. It has two options:
signal
: An AbortSignal that aborts the timeout. The delay function will reject.persistent
(only available in Deno): Indicates whether the process should continue to run as long as the timer exists. This istrue
by default.
import { delay } from "https://deno.land/x/timers@v0.2.0/mod.ts";
const MSG = "Please type your name";
const info = document.querySelector("p.info");
const nameInput = document.querySelector("input.name");
const abort = new AbortController();
const { signal } = abort;
nameInput.addEventListener("input", () => abort.abort(), { once: true });
await delay(2000, {
signal,
});
info.textContent = MSG;
times
Another function timers
provides is times
. It is basically like
setInterval
, but executes the interval just a certain number of times. Like
with delay
, you have the signal
and persistent
(only available in Deno)
options, plus the silent
(supresses errors in the callback) and the args
option. Instead of passing the args as rest parameter, like with setInterval
,
you must pass them as array
, in order to have the other options.
import { times } from "https://deno.land/x/timers@v0.2.0/mod.ts";
const paragraph = document.querySelector("p.numbers");
const abortBtn = document.querySelector("button.abort");
const abort = new AbortController();
const { signal } = abort;
abortBtn.addEventListener("click", () => abort.abort(), { once: true });
let i = 0;
times(
() => {
paragraph.textContent += `${i}, `;
i++;
},
200,
20,
{
signal,
},
);
every
every
is syntactical sugar over an Interval
. The function returns an Every
class instance. To start the interval, you call do()
with your callback. To
set how often the callback should get executed, call limit()
on it, but only
before you call do()
. Calling stop()
aborts the interval. It supports the
following options:
signal
persistent
args
silent
import { every } from "https://deno.land/x/timers@v0.2.0/mod.ts";
every("1min").limit(60).do(() => {
console.log(new Date().toLocaleTimeString());
});
after
after
is like every
, but for timeouts. It does, of course, not have the
limit
function, since it gets only executed once. The following options are
available:
signal
persistent
args
silent
import { every } from "https://deno.land/x/timers@v0.2.0/mod.ts";
after("1min").do(() => {
console.log(new Date().toLocaleTimeString());
});
pTimeout
Adapted from p-timeout Timeout a promise after a specified amount of time.
import { delay, pTimeout } from "https://deno.land/x/timers@v0.2.0/mod.ts";
const delayedPromise = delay(500);
await pTimeout(delayedPromise, 50);
// => [TimeoutError: Promise timed out after 50 milliseconds]
The function expects at least two arguments:
promise
: APromise
or a function returning aPromise
delay
: The time in milliseconds after which the function rejectsoptions
(not required):signal
: AnAbortSignal
to abort the function even before it rejectsfallbackFn
: Do something other than rejecting with an error on timeout. You could for example retry.failMessage
: A custom error message. Default:'Promise timed out after 50 milliseconds'
failError
: Specify a customError
. Itās recommended to sub-class ofTimeoutError
.
It returns a decorated Promise
, which can be aborted with its abort()
method.
Using with a function
Instead of passing a Promise
directly, you can pass a function that retuns a
Promise
:
import { pTimeout } from "https://deno.land/x/timers@v0.2.0/mod.ts";
const pingApi = () => fetch("/api");
await pTimeout(pingApi, "50 ms");
The function can take an AbortSignal
as parameter as well, which abort
event
fires, when the timeout times out:
import { pTimeout } from "https://deno.land/x/timers@v0.2.0/mod.ts";
const pingApi = (signal) => fetch("/api", { signal });
await pTimeout(pingApi, 50);
pTimeout
also passes down the signal it got:
import { delay, pTimeout } from "https://deno.land/x/timers@v0.2.0/mod.ts";
const abort = new AbortController();
const { signal } = abort;
const pingApi = (signal) => fetch("/api", { signal });
pTimeout(pingApi, "100milliseconds", { signal });
delay(50).then(() => abort.abort());
timeout
and interval
timeout
and interval
are like setTimeout
and setInterval
, but are typed,
support time strings
meaning that the args
optionās type must equal the type
of the argument expected by the callback. and supports these options:
signal
persistent
(only available in Deno)args
times
(onlyinterval
)
import { interval, timeout } from "https://deno.land/x/timers@v0.2.0/mod.ts";
const timeout = timeout(() => {
console.log("in 30 days");
}, "30 days");
const interval = setInterval(() => {
console.log("every 30 days");
}, "30 days");
// Clear them
clearTimeout(timeout);
clearInterval(interval);
Timeout
and Interval
classes
Under the hood, all of the functions listed above use the Timeout
and
Interval
classes.
They are exported as well and you can use them to create timeouts without
running them directly.
import { Timeout } from "https://deno.land/x/timers@v0.2.0/mod.ts";
const notifyBtn = document.querySelector("button.notify");
const timeout = new Timeout(() => {
console.log("hello world");
}, 1000);
// WARNING: running a timeout two times will throw an error
notifyBtn.addEventListener("click", () => timeout.run(), { once: true });
For Timeout
, the following options are available:
signal
persistent
(only available in Deno)silent
args
times
(only forInterval
)
Properties
id
: The Id of the timer, can be used withclearTimeout
andclearInterval
aborted
: A Promise, that resolves, when the timer gets aborted, but only, if the abort happens with a call of theabort
method or the abortion via anAbortController
.isAborted
: A boolean indicating whether the timer has been abortedpersistent
(only available in Deno): A boolean indicating whether the process should continues running as long as the timer exists. This istrue
by default.- deprecated:
timer
: The Id of the timer. Useid
instead. ran
: A boolean indicating whether the timer ran already. Gets only set totrue
onInterval
when thetimes
option has been passed and the interval has runtimes
times.running
: A boolean indicating whether the timeout is currently running
Interval only
runs
: A number representing the amount of times the interval has run since now
Methods
run()
: runs the timeout and returns the timeoutās idabort(reason?: any)
: aborts the timeoutunref()
: makes the process not continue to run as long as the timer existsref()
: makes the process continue to run as long as the timer exists
NOTE
It is not possible to use Deno.unrefTimer() or Deno.refTimer() directly with the id returned by setInterval or setTimeout
Running Tests
To run tests, clone the repository, and run the following command
deno test
or, without cloning
deno test https://deno.land/x/timers@v0.2.0/test.ts
Contributing
Contributions are always welcome!
You found a bug or have an idea about a function, that is not yet implemented in
this module?
Feel free to open an issue or a
PR!