Как эффективно связать Rx JS Observables - PullRequest
1 голос
/ 24 апреля 2020

Я знаю, что этот вопрос несколько раз задавался здесь в разных формах, но я изо всех сил стараюсь, чтобы это делало именно то, что я хочу.

Для некоторого контекста у меня есть служба загрузки файлов в NodeJS, которая хранит изображения во временной папке. Затем у меня есть некоторые функции для изменения размера изображения (изображений) до обычного размера в Интернете и миниатюры, затем сохранение в папке загрузки, а затем другая функция для удаления временного файла. Все три из этих функций возвращают наблюдаемые.

Я хочу запустить эти наблюдаемые в последовательности, например,

observableA().subscribe((result) => //do something here ) // Resize the photo
observableB().subscribe((result) => //do something here ) // Create a thumbnail
observableC().subscribe((result) => //do something here ) // Delete the temporary file

Я хочу убедиться, что A и B завершены перед выполнением C (удаление временной папки). Я не хочу вкладывать Observables. И A и B возвращают некоторые данные, которые я хочу.

Какой оператор rx JS является лучшим для достижения этой цели?

Ответы [ 3 ]

2 голосов
/ 24 апреля 2020

Вы можете использовать forkJoin для объединения первых 2 наблюдаемых (они будут работать параллельно). Затем используйте switchMap для переключения на 3-ю наблюдаемую.

import { of, timer, forkJoin } from "rxjs";
import { switchMap, delay, map } from "rxjs/operators";

const observableA = of("resized photo").pipe(delay(300));
const observableB = of("thumbnail").pipe(delay(250));
const observableC = of("temp deleted").pipe(delay(100));

const result = forkJoin(observableA, observableB).pipe(
  switchMap(([resultA, resultB]) => {
    console.log(resultA, resultB);
    console.log('now to observableC');
    return observableC.pipe(map(resultC => [resultA, resultB, resultC]));
  })
);
result.subscribe(x => console.log(x));

Проверьте это на stakblitz (не забудьте открыть консоль, чтобы увидеть console.log выходы). * Документы 1009 *

Rx JS также имеют удобную страницу, которая помогает выбрать правильного оператора для работы: дерево решений оператора

0 голосов
/ 24 апреля 2020

Чтобы сохранить порядок, вы должны использовать оператор concatMap и оператор tap для таких побочных эффектов, как:

observableA()
  .pipe(
    concatMap(() => observable().pipe(tap(() => /* add some sides effects for this obs. */ )),
    tap(() => /* or add some sides effects here or somewhere else */ )),
    concatMap(() => observableC())
  )
  .subscribe();

0 голосов
/ 24 апреля 2020

Вы должны использовать flatMap, что в некотором смысле then для наблюдаемых, имея в виду, что flatMap фактически выполняет функцию.

this._myService.do1()
  .flatMap(function(x){return functionReturningObservableOrPromise(x)})
  .flatMap(... return observable here tooo)
  .subscribe(get your data)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...