Подтвердить что ты не робот

Поведение Promise.all с RxJS Observables?

В Angular 1.x мне иногда нужно было сделать несколько запросов http и сделать что-то со всеми ответами. Я бы выбрал все promises в массиве и вызвал Promise.all(promises).then(function (results) {...}).

Angular 2 лучшие практики, похоже, указывают на использование RxJS Observable в качестве замены promises в запросах http. Если у меня есть две или более разные Наблюдения, созданные из http-запросов, эквивалентны ли они этим Promise.all()?

4b9b3361

Ответ 1

Более простой альтернативой для эмуляции Promise.all является использование оператора forkJoin (он запускает все наблюдаемые параллельно и соединяет их последние элементы):

Немного из области видимости, но в случае, если это помогает, в связи с цепочкой promises вы можете использовать простой flatMap: Cf. RxJS Promise Composition (передача данных)

Ответ 2

forkJoin тоже отлично работает, но я бы предпочел объединение, так как вам не нужно беспокоиться об этом, принимая последнее значение наблюдаемых. Таким образом, вы можете просто получать обновления всякий раз, когда любой из них тоже выдает новое значение (например, вы выбираете на интервале или что-то).

Ответ 3

На reactivex.io forkJoin фактически указывает на Zip, который сделал работу для меня:

let subscription = Observable.zip(obs1, obs2, ...).subscribe(...);

Ответ 4

Обновление мая 2019 года с использованием RxJs v6

Нашли другие ответы полезными и хотели бы привести пример ответа Арно на использование zip.

Вот фрагмент, показывающий эквивалентность между Promise.all и rxjs zip (обратите внимание также, что в rxjs6 показано, как zip теперь импортируется с использованием "rxjs", а не как оператора).

import { zip } from "rxjs";

const the_weather = new Promise(resolve => {
  setTimeout(() => {
    resolve({ temp: 29, conditions: "Sunny with Clouds" });
  }, 2000);
});

const the_tweets = new Promise(resolve => {
  setTimeout(() => {
    resolve(["I like cake", "BBQ is good too!"]);
  }, 500);
});

// Using RxJs
let source$ = zip(the_weather, the_tweets);
source$.subscribe(([weatherInfo, tweetInfo]) =>
  console.log(weatherInfo, tweetInfo)
);

// Using ES6 Promises
Promise.all([the_weather, the_tweets]).then(responses => {
  const [weatherInfo, tweetInfo] = responses;
  console.log(weatherInfo, tweetInfo);
});

Вывод из обоих одинаков. Запуск выше дает:

{ temp: 29, conditions: 'Sunny with Clouds' } [ 'I like cake', 'BBQ is good too!' ]
{ temp: 29, conditions: 'Sunny with Clouds' } [ 'I like cake', 'BBQ is good too!' ]