concat
Lazily yields all of the first iterable, then all of the second.
Lecture
concat chains two iterables end to end without copying
either one into a new list. It's fully lazy on both sides: the second
iterable is never touched at all unless the pipeline actually pulls past
the end of the first — so concatenating an expensive or infinite first
source with a second one is safe as long as you don't demand more than
the first source has.
concatAsync is a pass-through, like take and
concat's async cousins: it doesn't serialize either side
internally, so a concurrent(n) further downstream still
gets to overlap pulls against whichever side is currently active.
Demo 1 · Basics & laziness
The second iterable is a generator with a side effect — watch it never
run because take(2) is satisfied by the first list alone:
Demo 2 · Async
Try it yourself
Exercise: concatenate morning and evening
into one schedule.