Почему оператор switchMap выдает только последнее значение при использовании с обещанием?

У меня есть некоторые проблемы, чтобы понять это. Когда я использую оператор switchMap с Observable, он выдает все значения, как и ожидалось:

Observable.from([1, 2, 3, 4, 5])
    .do(console.log)
    .switchMap(i => Observable.of('*' + i))
    .do(console.log)
    .subscribe();

Результаты:

1
*1
2
*2
3
*3
4
*4
5
*5

Но когда я заменяю Observable на Promise, я получаю другое поведение:

Observable.from([1, 2, 3, 4, 5])
    .do(console.log)
    .switchMap(i => new Promise((resolve) => resolve('*' + i)))
    .do(console.log)
    .subscribe();

Результаты:

1
2
3
4
5
*5

2 ответа

Решение

Это работает как ожидалось. Неожиданное поведение, как вы сказали, потому что Observable.from а также Observable.of всегда строго синхронны в то время как new Promise не обязательно (я не уверен насчет спецификации, так что, возможно, именно это Promise должен делать во всех браузерах).

В любом случае вы можете заставить Observable.from излучать асинхронно, передавая async Планировщик.

import { Observable } from 'rxjs';
import { async } from 'rxjs/scheduler/async';

Observable.from([1, 2, 3, 4, 5], async)
    .do(console.log)
    .switchMap(i => new Promise((resolve) => resolve('*' + i)))
    .do(console.log)
    .subscribe();

Теперь каждый выброс в новом кадре, как Promise и результат, как вы ожидали.

Смотрите живую демонстрацию (открытая консоль): https://stackblitz.com/edit/rxjs5-gfeqsn?file=index.ts

ПытатьсяmergeMap, возможно, это то, что вы ищете.

Другие вопросы по тегам