The Repeater class
class Repeater<T, TReturn = any, TNext = unknown> {constructor(executor: RepeaterExecutor<T, TReturn, TNext>, buffer?: RepeaterBuffer,);}
The Repeater object represents an asynchronous sequence of values. The Repeater class implements the AsyncIterableIterator interface and can be consumed using a for await…of loop or by calling the next, return and throw methods directly.
The type parameters T, TReturn and TNext correspond to the type parameters passed to the AsyncIterator interface provided by the built-in TypeScript library.
constructor
Parameters
executor- A function which is called when the repeater is started.buffer- An optional buffer object which allows the repeater to store or drop values.
The executor function
type RepeaterExecutor<T, TReturn = any, TNext = unknown> = (push: Push<T, TNext>,stop: Stop,) => PromiseLike<TReturn> | TReturn;
The executor passed to the repeater is called with the arguments push and stop. These arguments can be used to manipulate the state of the repeater.
If the executor throws an error, the repeater is automatically stopped and the final iteration rejects with the error. If the executor returns normally, the return value of the executor is used as the final value of the repeater.
The push argument
type Push<T, TNext = unknown> = (value: PromiseLike<T> | T,) => Promise<TNext | undefined>;
The push argument is a function which can be called with a value to enqueue the value on the repeater. Consumers can then pull the pushed value using Repeater.prototype.next. If the value passed to push is a promise, the repeater unwraps the promise before passing it to consumers.
The push function synchronously throws an error if there are too many pending pushes on the repeater.
Parameters
value- the value to pass to repeater consumers.
Return value
The push function returns a promise which fulfills or rejects depending on the state of the repeater:
- If the repeater is stopped, the returned promise resolves to
undefined. - If the repeater has a non-empty buffer, the returned promise resolves to
undefined. Repeater.prototype.nextresolves the previouspushcall to the value passed to thenextmethod. If the repeater is consumed using afor await…ofloop, this promise resolves toundefined.- If
Repeater.prototype.throwis called, the previouspushcall rejects. It is not necessary to use or catch the returned promise because repeaters detects when the promise is unhandled and rethrow its rejection to the caller of thethrowmethod.
The stop argument
type Stop = ((error?: any) => undefined) & Promise<undefined>;
The stop argument is both a function and a promise.
Parameters
- error: An optional error.
As a function, stop can be called to stop the repeater, preventing any further values from being pushed. Calling stop without arguments stops the repeater without error, and calling stop with an error both stops the repeater and causes the final iteration to reject with that error.
As a promise, stop resolves when stop is called, when Repeater.prototype.return is called, when a promise rejection is passed to push, or when the executor throws an error. It can be awaited to defer event handler cleanup, and it can be used with Promise.race to abort pending promises. The stop promise always resolves to undefined and never rejects.
Repeater.prototype.next
class Repeater {next(value?: PromiseLike<TNext> | TNext): Promise<IteratorResult<T>>;}
The next method returns an object with the properties done and value. You can also provide a parameter to the next method to send a value back to the repeater.
Parameters
value- The value to send to the repeater. The previouspushcall resolves to this value.
Return value
A promise which fulfills to an object with the following properties:
done- a boolean which indicates whether there are more values to be pulled.value- If
doneis true,valueis either beundefinedor the return value of theexecutor. - If
doneis false thevalueis a value passed topush.
- If
The next function synchronously throws an error if there are too many pending calls to next on the repeater.
Repeater.protoype.return
class Repeater {return(value?: PromiseLike<TReturn> | TReturn): Promise<IteratorResult<T>>;}
The return method prematurely finishes the repeater. When returned, any pending values on the repeater are dropped. Additionally, the executor’s return value is ignored.
Parameters
value- The value to return. Ifvalueis a promise,returnawaits the value before returning it.
Return value
A promise which fulfills to an object with following properties:
done- truevalue- the value passed toreturn.
Repeater.prototype.throw
class Repeater {throw(error?: any): Promise<IteratorResult<T>>;}
The throw method causes the previous push call to reject with the given error. If the executor fails to handle the error, the throw method rethrows the error and finish the repeater. A throw method call is detected as unhandled in the following situations:
- The repeater has not started (
Repeater.prototype.nexthas never been called). - The repeater has stopped.
- The repeater has a non-empty buffer.
- The promise returned from the previous push call has not been awaited and its
then/catchmethods have not been called.
Parameters
error- The error to send to the repeater.
Return value
A promise which fulfills to the next iteration result if the repeater handles the error, and otherwise rejects with the given error.
The RepeaterBuffer interface
The Repeater constructor optionally takes a RepeaterBuffer object as its second argument. Buffers allow multiple values to be pushed onto a repeater without having pushes wait.
export interface RepeaterBuffer {full: boolean;empty: boolean;add(value: unknown): void;remove(): unknown;}
The FixedBuffer class
class FixedBuffer implements RepeaterBuffer {constructor(capacity: number);}
The FixedBuffer object allows repeaters to push a set number of values without having pushes wait or throw errors. When the limit is reached, the repeater behaves as it would without a buffer.
constructor
parameters
capacity- The maximum number of values that can be added to buffer.
The SlidingBuffer class
class SlidingBuffer implements RepeaterBuffer {constructor(capacity: number);}
The SlidingBuffer object allows repeaters to push unlimited values without having pushes wait or throw errors. When the buffer reaches the specified capacity, the buffer drops the earliest values passed to the buffer.
constructor
parameters
capacity- The maximum number of values that can be added to the buffer before the buffer drops values.
The DroppingBuffer class
class DroppingBuffer implements RepeaterBuffer {constructor(capacity: number);}
The DroppingBuffer object allows repeaters to push unlimited values without having pushes wait or throw errors. When the buffer reaches the specified capacity, the buffer drops the latest values passed to the buffer.
constructor
parameters
capacity- The maximum number of values that can be added to the buffer before the buffer drops values.
Repeater.race
Repeater.race = function <T>(contenders: Iterable<T>,): Repeater<T extends AsyncIterable<infer U> | Iterable<infer U>? U extends PromiseLike<infer V>? V: U: never>;
Parameters
contenders- An iterable of async iterables, iterables or promises.
Return value
A repeater which yields the first settling value from each iterable for each iteration. If any iterables finishes, the repeater returns with that iterable’s final value. Promises are treated as an async iterator which returns the value when the promise fulfills.
Repeater.merge
Repeater.merge = function <T>(contenders: Iterable<T>,): Repeater<T extends AsyncIterable<infer U> | Iterable<infer U>? U extends PromiseLike<infer V>? V: U: T extends PromiseLike<infer U>? U: T>;
Parameters
contenders- An iterable of async iterables, iterables or promises.
Return value
A repeater which yields values from each iterable as they settle. When all iterables finish, the repeater returns with the final value of the last iterator which finished. Promises are treated as an async iterator which yields the value when the promise fulfills.
Repeater.zip
type Contender<T>= AsyncIterable<Promise<T> | T>| Iterable<Promise<T> | T>| PromiseLike<T>| T;Repeater.zip = function <T>(contenders: Iterable<Contender<T>>,): Repeater<T[]>;
Parameters
contenders- An iterable of async iterables, iterables or promises.
Return value
A repeater which yields a tuple of values taken from each iterable for each iteration. When any iterable finishes, the repeater returns a tuple of values from each iterator. Promises are treated as an async iterator which returns the value when the promise fulfills.
Repeater.latest
type Contender<T>= AsyncIterable<Promise<T> | T>| Iterable<Promise<T> | T>| PromiseLike<T>| T;Repeater.latest = function <T>(contenders: Iterable<Contender<T>>,): Repeater<T[]>;
Parameters
contenders- An iterable of async iterables, iterables or promises.
Return value
A repeater which yields a tuple of values taken from each iterable. The repeater yields a tuple of values whenever any of the contenders yields values. The repeater does not yield a value until every iterable has yielded a value at least once. When any iterable finishes, the repeater returns a tuple of the final values from each iterator. Promises are treated as an async iterator which both yields and returns the value when the promise fulfills.
RepeaterOverflowError
class RepeaterOverflowError extends Error {constructor(message: string);}
A RepeaterOverflowError is thrown when the push function or next method is called on a repeater with too many pending push or next operations.
constructor
parameters
message- A human-readable description of the error.
MAX_QUEUE_LENGTH
const MAX_QUEUE_LENGTH = 1024;
A constant which represents the maximum number of pending push or next operations which can be enqueued on a single repeater.