Abdullah Rasheed
Abdullah Rasheed

Reputation: 3752

Convert Promise.all into Observable

I need to make several async calls that depend on each other. I initially wrote the code and used Promise.all to make async in steps. I looped through my data and created a async method in order to put all of the needed actions into an array to pass into Promise.all(). This works fine, but how could I do the same using Observables. I've read that forkJoin is the equivalent of Promise.all, but how could i loop through the data and wrap my async function, and then execute it before moving to the next flatMap?

public getMonthly(){
return this.http.get(url)
            .flatMap(response => {
                // need to convert this?
                let actions = response.json().map(this.asyncMonthlyRecord);
                return Promise.all(actions); 
            })
            .flatMap(()=> this.queryMonthly())
            .map(this.convertFromSQl)
            .catch((error:any)=> Observable.throw(error || 'Server Error'));
}

private asyncMonthlyRecord = (record):Promise<any> => {
      return this.setUsage(record,'HILowMonthly');
}

private queryMonthly(){
      return this.storage.query('SELECT * FROM HILowMonthly')
}

 getMonthly().subscribe(x => console.info(x)); // logs data from SQLite perfectly...

Upvotes: 0

Views: 770

Answers (1)

dotcs
dotcs

Reputation: 2296

I think what you want is something like this

Rx.Observable.of({ itemIds: [1, 2, 3, 4, 5 ]})
  .mergeMap(response => {
    const promises = response.itemIds
      .map(id => {
        return new Promise((resolve, reject) => {
          // Wait for some random time, then resolve the promise.
          const timeout = Math.floor(Math.random() * 5000);
          setTimeout(() => {
            console.log(`Finished promise ${id}`); // debug only
            resolve({id, resolved: true}) 
          }, timeout);
        });
      });
    // Wait until all Promises have been resolved, then return all
    // of them in a single and ordered array.
    return Rx.Observable.forkJoin(promises);
  })
  .subscribe(x => console.log(x));

Working code on jsbin

Notice that the promises resolve in an arbitrary order but are returned in the correct order. The commented code in the jsbin example also shows each promise could be resolved individually and merged back into the original stream in case the order of the promises is not important.

Upvotes: 1

Related Questions