Creates a task handing every item to several branches.
Each task is applied to the feed as a branch of its own and handed every item, so one pass over the source is
reshaped, observed or routed several ways at once; the items the branches report are interleaved into a single
feed, emitted as soon as each is ready.
Branches draw in lockstep: an item is drawn only once every branch still running has taken the one on offer, so
nothing is held beyond that item and the source advances at the pace of the slowest branch. A branch closing early
drops out and stops holding back the others; a branch reporting nothing simply contributes nothing.
Warning
Incremental: items are emitted as the branches report them, so the reported feed runs dry as the feed drawn
from and every branch do.
Streaming: one item is on offer at a time and none is retained, whatever the branches retain.
Stateless: the fan-out carries no state across items, whatever the branches carry.
Warning
Output order is not preserved: the items of the branches interleave and overtake each other according to how long
every branch takes, though the items of each branch keep their own order among themselves.
Caution
A branch idling while still running holds back every other one, as the item on offer is replaced only once all of
them have taken it: pacing and long-running work belong downstream of the fan-out, where they no longer hold the
branches together.
Note
Every branch draws the whole feed, so state a task initialises on invocation decides on every item, as it would
anywhere else in the pipe: a quota, a deduplication or an ordering covers the feed entire.
Note
Branches failing while the consumer is idle report their error when the feed is next advanced, rather than
escaping as unhandled rejections.
Note
Every branch and the source are closed when the feed is exhausted, fails or is closed early, waiting for the work
already in flight to settle first, so a source idling between items delays it; failures reported while closing
are suppressed.
A task yielding the items every branch reports, as they become available
Example
awaitpipe( (items([1, 2, 3])) (tee(map(n=>n*2), filter(n=>n > 2))) (toArray()) ); // 2, 4, 6 from the doubling branch and 3 from the filtering one, interleaved in no defined order
Creates a task handing every item to several branches.
Each task is applied to the feed as a branch of its own and handed every item, so one pass over the source is reshaped, observed or routed several ways at once; the items the branches report are interleaved into a single feed, emitted as soon as each is ready.
Branches draw in lockstep: an item is drawn only once every branch still running has taken the one on offer, so nothing is held beyond that item and the source advances at the pace of the slowest branch. A branch closing early drops out and stops holding back the others; a branch reporting nothing simply contributes nothing.
Output order is not preserved: the items of the branches interleave and overtake each other according to how long every branch takes, though the items of each branch keep their own order among themselves.
A branch idling while still running holds back every other one, as the item on offer is replaced only once all of them have taken it: pacing and long-running work belong downstream of the fan-out, where they no longer hold the branches together.
Every branch draws the whole feed, so state a task initialises on invocation decides on every item, as it would anywhere else in the pipe: a quota, a deduplication or an ordering covers the feed entire.
Branches failing while the consumer is idle report their error when the feed is next advanced, rather than escaping as unhandled rejections.
Every branch and the source are closed when the feed is exhausted, fails or is closed early, waiting for the work already in flight to settle first, so a source idling between items delays it; failures reported while closing are suppressed.