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.
65 lines
4.9 KiB
65 lines
4.9 KiB
# 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.
|
|
|
|
## Methods
|
|
|
|
There are two methods on the class `AsyncTimeout(func, time)`:
|
|
* `timeout()`: Creates an `await`able promise that will resolve to the value of `func()` when the timeout `time` is reached.
|
|
* `interval()`: Creates a `for await`able 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`.
|
|
|
|
## Parameters
|
|
* `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 *acquire*ing 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.
|
|
|
|
## Methods
|
|
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`.)
|
|
|
|
## Parameters
|
|
|
|
* `cap`: An integer larger than 0 which dictates how many locks can be acquired at one time before *acquire*ing methods need to wait for one to be available.
|
|
|
|
## Fields
|
|
|
|
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 *acquire*ing methods must wait for a lock to be released.
|