toy
toy

Reputation: 12151

How do I wait until all the Promises are fulfilled in RxJS?

I have a list of Promises that I want to get the result and display on the page.

 let directives = ['object-src', 'img-src', 'media-src', 'script-src', 'style-src', 'frame-src', 'child-src'];

 let directivesStream = Rx.Observable.from(directives)
   .map((d) => {
     let q = getSummaryCSP({
       origin: origin,
         directive: d,
         from: moment().subtract(3, 'days').utc().format(),
         to: moment().utc().format()
     });

     return Rx.Observable.interval(10000)
       .flatMap(() => Rx.Observable.fromPromise(queries.query(q)));
   });

 directivesStream.mergeAll().subscribe((response) => {
   let flattenedRes = _.sortBy(response.data, (e) => e.event.count);
   flattenedRes = _.reverse(flattenedRes);
   this.setState({
     cspReport: flattenedRes
   });
 });

So what it's doing is it creates a stream of Promises with interval of 10000. However, the end result is the combined results of all the promises that's why I'm doing sorting and reversing and then display the result in React.

I know that everything in RxJs is a stream. So, I'm not sure if I can achieve this at all?

So, my question is how do I create a stream of Promises that at the end 10s, all the streams have to be merged into one stream so I can use the result of all the promises.

Upvotes: 0

Views: 1519

Answers (2)

user3743222
user3743222

Reputation: 18665

Not sure if I understand your question well, but here are a few pointers for you to investigate:

  • toArray operator : allow to gather all emissions of a streams into an array
  • forkJoin operator : equivalent to Promise.all, runs all promises in parallel and gather all results

I am confident that with one of those two you can achieve your goal. I let you figure out which as trying to solve a problem by oneself is the best way to get a good understanding of Rxjs. You can in addition find a list of operators here. I recommend you to have a look before posting a question.

Upvotes: 2

G. Lee
G. Lee

Reputation: 11

Since you can import node modules into your client side code in React, I would take a look at the Async node module. I believe the execution process you want to happen is a combination of map and waterfall.

async.waterfall([
    myFirstFunction,
    mySecondFunction,
    myLastFunction,
], function (err, result) {
    // result now equals 'done'
});
function myFirstFunction(callback) {
    callback(null, 'one', 'two');
}
function mySecondFunction(arg1, arg2, callback) {
    // arg1 now equals 'one' and arg2 now equals 'two'
    callback(null, 'three');
}
function myLastFunction(arg1, callback) {
    // arg1 now equals 'three'
    callback(null, 'done');
}

Upvotes: 0

Related Questions