# 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.