Как я могу переключаться между двумя Наблюдаемыми по порядку, и подписка срабатывает дважды? - PullRequest
0 голосов
/ 23 марта 2020

Я использую Rx JS. У меня есть две Observables (вызовы API), которые возвращают разное количество информации для одного и того же массива. Я хочу переключаться между Observables и сделать так, чтобы подписка распознавала оба результата, т.е. срабатывает каждый раз, когда возвращается значение.

Вот пример использования Typescript (это не работает):

let foo = [];
const callOne$ = this.service.getSomeData$; // this should take 0.5 seconds
const callTwo$ = this.service.getAllTheData$; // this should take 6 seconds

callOne$.pipe(
    switchMap(data => data.length > 0 ? callTwo$ : of(data)
).subscribe(data => {
    console.log(data); // this fires once but I want it to fire twice
    foo = data;
});

Приведенный выше пример возвращает callOne$, затем возвращает callTwo$, а затем выдает результат. Вместо этого я хочу результаты обоих в порядке. Как мне подписаться на Observables, чтобы первый результат был получен, а затем обновлен вторым вызовом?

Ответы [ 2 ]

1 голос
/ 23 марта 2020

Самый простой способ может быть

merge(callOne$, callTwo$)
.subscribe(data => { 
    console.log(data); // this fires twice but results are not guaranteed to be ordered
    foo = data;
});

. Вы можете сохранить заказ, но при этом будет отправлено одно событие с чем-то вроде этого

forkJoin(callOne$, callTwo$)
.subscribe(([data1, data2]) => { // this fires once with both results ordered
     console.log(data1); 
     console.log(data2);
     foo = data;
 });

Если вы хотите, чтобы 2 отдельных уведомления поддерживались порядок, то есть сначала результат callOne $, а затем результат callTwo $, вы можете попытаться использовать оператор expand, например, такой:

callOne$.pipe(
  expand(val => callTwo$),
  take(2)  // to make sure you do not call callTwo$ infinitely
)
.subscribe(data => { 
  console.log(data); // this fires twice and the results are guaranteed to be ordered
  foo = data;
});

Рассматривая тот факт, что foo является массивом , вы можете быть склонны к использованию forkJoin, то есть второго варианта.

Более подробное объяснение вы можете найти в этой статье .

0 голосов
/ 26 марта 2020

Я обнаружил, что лучшим результатом является использование concat(), которое отвечает на наблюдаемые результаты в следующем порядке.

Другими словами:

concat(callOne$, callTwo$)
.subscribe(data => {
    console.log(data); // this will fire twice
    foo = data;
});

Этот код вернет два результата для data, обновляя переменную в порядке списка concat().

...