AsyncSequence
An AsyncSequence
iterates over its elements asynchronously when #each is called.
You get an AsyncSequence
by calling Sequence#async on any sequence. Note that some sequence types may not support asynchronous iteration.
Returning values
Because of its asynchronous nature, an AsyncSequence
cannot be used in the same way as other sequences for functions that return values directly (e.g., reduce
, max
, any
, even toArray
).
Instead, these methods return an AsyncHandle
whose onComplete
method accepts a callback that will be called with the final result once iteration has finished.
Defining custom asynchronous sequences
There are plenty of ways to define an asynchronous sequence. Here's one.
- First, implement an Iterator. This is an object whose prototype has the methods Iterator#moveNext (which returns a
boolean
) and current (which returns the current value). - Next, create a simple wrapper that inherits from
AsyncSequence
, whosegetIterator
function returns an instance of the iterator type you just defined.
The default implementation for #each on an AsyncSequence
is to create an iterator and then asynchronously call Iterator#moveNext (using setImmediate
, if available, otherwise setTimeout
) until the iterator can't move ahead any more.
Signature
function AsyncSequence(parent, interval) { /*...*/ }
function AsyncSequence(parent, interval) { if (parent instanceof AsyncSequence) { throw new Error("Sequence is already asynchronous!"); } this.parent = parent; this.interval = interval; this.onNextCallback = getOnNextCallback(interval); this.cancelCallback = getCancelCallback(interval); }
Name | Type(s) | Description |
---|---|---|
parent | Sequence | A Sequence to wrap, to expose asynchronous iteration. |
interval | number? | How many milliseconds should elapse between each element when iterating over this sequence. Note that this interval applies even to the first value in the sequence; i.e., when calling each(), this much time will elapse before the first element is iterated.
|