Порядок выполнения операторов RxJS

Учитывая, что у меня есть следующий код:

private readonly postAction$ = new Subject();

postStream$ = this.postAction$.pipe(
    exhaustMap(() => {
      this.count ++;
      console.log('fired')
      return of('my other post');
    }),
    startWith(''),
    exhaustMap(()=> {
      this.count ++;
      console.log('fired first')
      return of('my post' + this.count);
    })
  )

На который я подписываюсь в своем шаблоне с помощью канала async.

Я не ожидал, что это сработает, но вывод на консоль был:

> fired first

Пока я не позвоню .next() по теме postAction$, первый console.log('fired') никогда не вызывается.

Каков контекст выполнения операторов RxJS? Как они работают? Я ожидал, что первая выхлопная карта должна выдать значение до того, как будут запущены остальные операторы. Не удалось найти ничего в документации по rxjs

Демонстрация stackblitz


person C_Ogoo    schedule 30.10.2019    source источник


Ответы (1)


Я думаю, что лучший способ найти ответ - это увидеть, что происходит за кулисами (я этого не делал, но надеюсь сделать это в будущем).

А пока вот как я вижу вещи.

Подумайте о ручье как о реке.
По реке пересекают лодки, которые в основном представляют собой излучаемые значения .
Есть также мосты, вы можете думать о них как о операторах. Для каждого моста могут потребоваться определенные условия, чтобы решить, какая лодка может продолжить свой путь, а какая нет.

Вот как я это себе представляю:

            The value from `startWith`
                     ↓
~~~~~~~~|~~~~~~~~|~~~B~~~~|~~~~~~~~

        ^        ^        ^
        |        |    `exhaustMap(() => {})`
        |        |
        |   `startWith('B')`
        |
`exhaustMap(() => {})`

Канал async внутренне подписывается на данный наблюдаемый объект (и отписывается от него). Я думаю о подписке как о процессе настройки реки и мостов. Лодок пока нет.
Но в этом случае лодка может стартовать со второго моста, а это значит, что первому не о чем будет рассказывать это.

Это, если вы разместите мосты так:

 postStream$ = this.postAction$.pipe(
    startWith(''),
    exhaustMap(() => {
      this.count ++;
      console.log('fired')
      return of('my other post');
    }),
    exhaustMap(()=> {
      this.count ++;
      console.log('fired first')
      return of('my post' + this.count);
    })
  )

Вы должны увидеть этот вывод в консоли:

fired
fired first
person Andrei Gătej    schedule 30.10.2019