0

I am building a module using Promises, where I make multiple http calls on multiple urls, parse the responses and then again make more http calls.

c = new RSVP.Promise({urls:[]}) //Passing a list of urls
c.then(http_module1) // Call the http module
.then(parsing_module) // Parsing the responses and extract the hyperlinks
.then(http_module2) // Making http requests on the data produced by the parser before.
.then(print_module) // Prints out the responses.

The problem is that - If I use a promise, I can not parse the modules unless all the http requests are made. This is because - Once a promise has been resolved or rejected, it cannot be resolved or rejected again.

Build my own version of promises or is there an alternate approach?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
tusharmath
  • 10,622
  • 12
  • 56
  • 83

2 Answers2

2

You can write functions that return handles to your promises and create reusable parts that are still chainable. For example:

function getPromise(obj){
   return new RSVP.Promise(obj);
}
function callModule(obj){
   return getPromise(obj).then(http_module1);
}

var module = callModule({urls:[]})
  .then(getFoo())
  .then(whatever());

  //etc
J.Wells
  • 1,749
  • 12
  • 13
0

There are libraries that support such kind of pipes/streams, you don't need to build such yourself.

Yet the task seems to be doable with promises as well. Just don't use a single promise for an array of urls, but multiple promises - one for each url:

var urls = []; //Passing a list of urls
var promises = urls.map(function(url) {
    return http_module1(url) // Call the http module
      .then(parsing_module) // Parsing the responses and extract the hyperlinks
      .then(http_module2) // Making http requests on the data produced by the parser before.
      .then(print_module); // Prints out the responses.
});

This will run all of them in parallel. To wait until they have ran, use RSVP.all(promises) to get a promise for the results, see also https://github.com/tildeio/rsvp.js#arrays-of-promises

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Yes, you can do the same with `http_module2` – Bergi Apr 20 '14 at 17:46
  • You mean have another method instead of `http_module2` which returns a map promises? – tusharmath Apr 20 '14 at 17:49
  • No, `http_module2` would return a promise for the results of the hyperlinks, wouldn't it? Maybe you should post it's code as well so that I can include it in my answer as well. – Bergi Apr 20 '14 at 17:50
  • `http_module1` and `http_module2` basically have the same implementation. They take a key from the response of the previous promise and make an HTTP request. Once the http request is complete, they `resolve` the promise. – tusharmath Apr 20 '14 at 17:56
  • I could have added the code but I am still thinking about its implementation. Which can only be finalized if I know how I am going to use them. – tusharmath Apr 20 '14 at 17:57
  • `parsing_module` is supposed to extract one hyperlink from one response. This will be passed to `http_module2`, which returns a promise for the response of a request to that. – Bergi Apr 20 '14 at 18:00
  • Also, the modules themselves right now, in my head are not returning promises. If you think that's how it should be, then I wouldn't mind implementing them in that way – tusharmath Apr 20 '14 at 18:01
  • Yes, exactly, that's how `then` is supposed is to work. It takes a callback that will yield another promise. – Bergi Apr 20 '14 at 18:02
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/51058/discussion-between-tushar-and-bergi) – tusharmath Apr 20 '14 at 18:06