Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Promise.all behavior with RxJS Observables?

In Angular 1.x I would sometimes need to make multiple http requests and do something with all the responses. I would throw all the promises in an array and call Promise.all(promises).then(function (results) {...}).

Angular 2 best practices seem to point towards the use of RxJS's Observable as a replacement to promises in http requests. If I have two or more different Observables created from http requests, is there an equivalent to Promise.all()?

like image 905
Corey Ogburn Avatar asked Feb 24 '16 16:02

Corey Ogburn


People also ask

Can we convert RxJS Observable into a Promise?

Conversion to Promiseslink. The similarity between Observables and Promises is that both collections may produce values over time, but the difference is that Observables may produce none or more than one value, while Promises produce only one value when resolved successfully.

Which is better Promise or Observable?

The biggest difference is that Promises won't change their value once they have been fulfilled. They can only emit (reject, resolve) a single value. On the other hand, observables can emit multiple results. The subscriber will be receiving results until the observer is completed or unsubscribed from.

What is the difference between combineLatest and forkJoin?

forkJoin - When all observables complete, emit the last emitted value from each. combineLatest - When any observable emits a value, emit the latest value from each.

How to join all promises in RxJS?

The more straightforward alternative for emulating Promise.all is to use the forkJoin operator (it starts all observables in parallel and join their last elements): A bit out of scope, but in case it helps, on the subject of chaining promises, you can use a simple flatMap : Cf. RxJS Promise Composition (passing data)

What is the use of RxJS observable?

RxJS Observables. An Observable is a unique Object similar to a Promise that can help manage async code. Observables are not part of the JavaScript language yet but are being proposed to be added to the language. Since we can’t use a built-in Observable, we rely on a popular Observable library called RxJS.

What is the difference between observables and promises in JavaScript?

One of the significant differences between Observables and Promises is Observables support the ability to emit multiple asynchronous values. A Promise once it has resolved its async value it completes and can no longer be used. The one shot use falls short for the use case where we need multiple values over time.

What is RxJS complete?

Most people will first encounter RxJS through observables. An observable will typically look something like this: These are based around the observable model or contract. Next is what handles emitting events in the stream. Complete frees up the observables resources and essentially ends the stream.


3 Answers

The more straightforward alternative for emulating Promise.all is to use the forkJoin operator (it starts all observables in parallel and join their last elements):

  • documentation
  • related link: Cf. RxJS: concat three promises, distinguish results

A bit out of scope, but in case it helps, on the subject of chaining promises, you can use a simple flatMap : Cf. RxJS Promise Composition (passing data)

like image 183
user3743222 Avatar answered Oct 11 '22 04:10

user3743222


Update May 2019 using RxJs v6

Found the other answers useful, and wished to offer an example for the answer offered by Arnaud about zip usage.

Here is a snippet showing the equivalence between Promise.all and the rxjs zip (note also, in rxjs6 how zip now gets imported using "rxjs" & not as an operator).

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);
});

The output from both are the same. Running the above gives:

{ 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!' ]
like image 27
arcseldon Avatar answered Oct 11 '22 03:10

arcseldon


forkJoin works fine too, but I'd prefer combineLatest since you don't need to worry about it taking the last value of observables. This way, you can just get updated whenever any of them emit a new value too (e.g. you fetch on an interval or something).

like image 13
kakigoori Avatar answered Oct 11 '22 03:10

kakigoori