A simple and featureful async interface for `setTimeout()` and `setInterval()`. And a simple and featureful interface for semaphores in async JavaScript.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Go to file
Avril b7f3249180
Update README for a section on `Semaphore` (semaphore.js).
2 years ago
README.md Update README for a section on `Semaphore` (semaphore.js). 2 years ago
asynctimeout.js AsyncTimeout: Now handles async functions for `thing` correctly. Improved `timeout_example(_timeout, cancel)` (+ `Cancellation` class for async cancellations). Added `try_example(time)` which runs the default example and cancels after `time`, returning the value or error in an object containing either `{ value: true }` or `{ error: <caught error> }` when awaited. 2 years ago
semaphore.js Update README for a section on `Semaphore` (semaphore.js). 2 years ago


AsyncTimeout - setTimeout() and setInterval() for async code.

The class AsyncTimeout(function, timeout). An async wrapper around setTimeout(), and an async iterator wrapper around setInterval(), which resolves to/yields the return value of the supplied function for both .timeout() and .interval() respectively.


There are two methods on the class AsyncTimeout(func, time):

  • timeout(): Creates an awaitable promise that will resolve to the value of func() when the timeout time is reached.
  • interval(): Creates a for awaitable async iterator that will resolve to the value of func() each time it is called. To cancel the interval, simply break from the loop or stop calling .next() on the returned async iterator.

Static methods

There are two helper functions in AsyncTimeout:

  • await_timeout(time): Returns a promise that resolves with no value after time.
  • await_interval(time): Returns an infinite async iterator that yields no value for every interval of time.


  • thing - The function to call after the timeout/interval. The result of the promise (or the yield for interval()) is the result of this function call. If the funtion throws, then the rejection of the promise will be that error thrown. If this is an async function, then it is awaited inside the returned/yielded promise, and its resolution becomes the resolved value for the returned/yielded promise; likewise, its rejection becomes the rejection for the returned/yielded promise.
  • interval - The time to wait for the timeout or interval

Example usages

See timeout_example(), or try_example() in the file for detail.

setTimeout() promisified

await (new AsyncTimeout(() => "value", 100)).timeout() /* === "value" */ is setTimeout(()=> "value", 100) promisified.

setInterval() async iterator-ifyed.

for await (const value of new AsyncTimeout(() => "value", 100)).interval()) { /* value === "value" */ } is setInterval(()=> "value", 100) with each interval promisified. value will be the result of each interval call, so the function passed can capture, interact with, and return whatever it wants during the interval and each value will be the result of it being called again at each interval (as is expected.)

This is an infinite iterator. To cancel the interval, simply break out of the for await loop or otherwise stop using the iterator returned from .interval().

Semaphore - A simple async seamphore implementation for JavaScript

The class Semaphore(cap) inside semaphore.js is a robust async semaphore implementation. Its locking permits are queued (meaning, multiple waiting acquireing calls will resolve in the order they are called.)

See the file semaphore.js for more information on how it's used, and the function sem_example(cap || 1) in that file.


Raw acquire/release of semaphore lock:

  • acquire_raw(): An async function that resolves when a lock is available, acquiring that lock. You must release_raw() this lock after its use.
  • release_raw(): A function that releases a semaphore lock, or passes it to a waiting acquireing call.
  • try_acquire_raw(): Attempts to acquire a semaphore lock if one is available, and returns true if one was available and the lock was taken, false if there were no available locks and one was not taken. If this function returns true, you must pair it with a release_raw() call after the lock has been used.

Automatic semaphore lock acquisition functions:

  • using(func): An async function that acquires a lock, runs func() (and awaits it if it is an async function), and then releases the lock no matter if the function threw or not.
  • bind_using(func): A function that returns a function that when invoked, acts as using(func). This can be used to bind functions to the semaphore to be executed later.
  • try_using(func, opt): A function that attempts to acquire a lock, runs func() if it can, releases the lock, then returns the value from the func() call if it succeeded. If a lock cannot be acquired, opt can be used to dictate what or how values are returned (see doc comment on try_using for more information on how to use this parameter, by default the return value on a failure to acquire a lock immediately is false.) If func is an async function, a promise is returned that when awaited, will release the lock and return the resolution of the promise (or throw the exception of the promise's rejection.)

Static methods

  • Semaphore.mutex(): Returns a new mutex (a Semaphore instance with a capacity of 1.)


  • cap: An integer larger than 0 which dictates how many locks can be acquired at one time before acquireing methods need to wait for one to be available.


These fields should almost never be modified directly.

  • length: The number of locks currently held.
  • capacity: The max number of concurrent locks allowed to be held before new acquireing methods must wait for a lock to be released.