Andon Mitev
Andon Mitev

Reputation: 1514

Handle multiple requests at the same time and update state when one of them is resolved

I have following scenario:

Multiple http requests will be executed:

const sourceOne = http.get(obj1.product_id);
const sourceTwo = http.get(obj2.product_id);
const sourceThree = http.get(obj3.product_id);
const sourceFour = http.get(obj4.product_id);

can i somehow using Promises or Observables to:

  1. Execute all of the requests at the same time
  2. Update state when one of them is resolved, for example:

All of the possible solutions that i can found are always wait for all of the requests to be completed before updating the state, any ideas?

Upvotes: 0

Views: 489

Answers (4)

MGX
MGX

Reputation: 3531

If you have RxJS installed, observables can do that.

All at once

forkJoin([sourceOne, sourceTwo, sourceThree, sourceFour])
  .subscribe(([one, two, three, four]) => {});

Update client when one of them resolves :

merge(sourceOne, sourceTwo, sourceThree, sourceFour)
  .subscribe(() => updateUi());

Upvotes: 0

Johan Swanepoel
Johan Swanepoel

Reputation: 482

You could make use of merge to turn multiple observables into a single observable.

merge(sourceOne, sourceTwo, sourceThree, sourceFour).subscribe((data) => updateState(data))

Here is a link to a stackblitz example: https://stackblitz.com/edit/rxjs-cg31qz?devToolsHeight=33&file=index.ts

Upvotes: 2

A4tur
A4tur

Reputation: 85

The answer to your question is Promise.race() which fires, everything in then() callback function, after one of the passed promises has been resolved.

const prom1 = new Promise(r => {
  setTimeout(() => {
    r('prom1')
  }, 1200)
})
const prom2 = new Promise(r => {
  setTimeout(() => {
    r('prom2')
  }, 600)
})
const prom3 = new Promise(r => {
  setTimeout(() => {
    r('prom3')
  }, 1000)
})
const prom4 = new Promise(r => {
  setTimeout(() => {
    r('prom4')
  }, 700)
})

Promise.race([prom1, prom2, prom3, prom4]).then(r => {
  console.log(r)
})

Upvotes: 0

Mina
Mina

Reputation: 17544

I think what you are looking for Promise.race, it will populate the first promise has been resolved.

The Promise.race() method returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects, with the value or reason from that promise.

const arr [obj1.product_id, obj2.product_id, obj3.product_id, obj4.product_id]

const result = Promise.race(arr.map(i => http.get(i))

Upvotes: 1

Related Questions