Задача
Что выведет код в консоль?
const a = new Subject();
const b = new Subject();
concatMap([a, b]).subscribe((v) => console.log("concatMap", v));
merge(a, b).subscribe((v) => console.log("merge", v));
a.pipe(switchMap(() => b)).subscribe((v) => console.log("switchMap", v));
a.next(1);
b.next(1);
a.next(2);
a.next(3);
b.next(2);Решение
Ответ
Сразу оговорка:
concatMap([a, b])— некорректный вызов (concatMapэто оператор, а не фабрика; здесь скорее подразумевалсяconcat(a, b)). Разберём осмысленную часть —mergeиswitchMap.merge(a, b) пробрасывает значения обоих потоков по мере их прихода:
merge 1 // a.next(1) merge 1 // b.next(1) merge 2 // a.next(2) merge 3 // a.next(3) merge 2 // b.next(2)a.pipe(switchMap(() => b)) — на каждый
a.nextпереключается наbи отписывается от предыдущего. Значенияbпробрасываются только после того, как пришло хотя бы одноa:
a.next(1)→ подписка наb;b.next(1)→switchMap 1;a.next(2)→ переподписка наb(тот же Subject);a.next(3)→ снова переподписка наb;b.next(2)→switchMap 2.switchMap 1 switchMap 2
Почему concat здесь «не работает»
concat(a, b)подписался бы наbтолько после завершенияa(a.complete()). Так какaникогда не комплитится, значенияbчерезconcatвообще не пройдут — вывод был бы только из значенийa.