1

I use the request-promise node module as following :

let rp = require('request-promise');

I have the following promises chain :

getData().then( data => {
  return getUser(data);
})
.then( data => {
  return getProfiles(data);
}).then( data => {
  updateAddresses(data);
});

The updateAddresses is as following :

function updateAddresses(data){
   var promises = data.map( (aProfile) => {
      var options = {url:'http://example.com', method:'POST'};
      return rp(options);
   });

   // Promise.all(promises).then(...);
}

So I'm preparing a promise (request-promise) for each element of the array.

The problem is that those promises are firing even when I remove Promise.all !

How is that possible ? How can I make the promise not firing ?

Regards.

Dae
  • 11
  • 3
  • `return` the `Promise.all()` in `updateAddresses`. – zero298 Aug 01 '17 at 18:56
  • I'm not sure if I explained well the problem : Before I use `Promise.all` I wanted to check the code as it is. And I noticed that the promises are getting resolved. I just want to store them in the promises array. – Dae Aug 01 '17 at 18:58
  • Then store the options, don't call `rp` on them until you're ready. You still need to return something from `updateAddresses` otherwise what you `map()` will be lost when the scope ends. – zero298 Aug 01 '17 at 19:00
  • Can you please post some code snippet on how I can store the options and apply a Promise.all on their promises ? – Dae Aug 01 '17 at 19:01
  • Of course they do. `Promise.all` is just a helper function that waits for multiple promises. Promises are result values, not actions to be executed. The request is fired when you call `rp` - not when you call `then`. – Bergi Aug 01 '17 at 20:42

2 Answers2

1

Your updateAddresses is not returning anything to call then() on and you aren't waiting on what would be coming out of updateAddress.

function updateAddresses(data){
   var promises = data.map( (aProfile) => {
      var options = {url:'http://example.com', method:'POST'};
      return rp(options);
   });

   //Return something to then()
   return Promise.all(promises).then(...);
}

Then wait on it:

getData().then( data => {
  return getUser(data);
})
.then( data => {
  return getProfiles(data);
}).then( data => {
  return updateAddresses(data);
}).then(e => somethingelse);

Per your requirement to store the mapped address Objects:

function updateAddresses(data) {
    return data.map((aProfile) => {
        return {
            url: 'http://example.com',
            method: 'POST'
        }
    });
}

getData()
    .then(data => getUser(data))
    .then(data => getProfiles(data))
    .then((data) => {
        let addressOptions = updateAddresses(data);
        /*
         * You now have an Array of Objects of the form:
         * {
         *     url: "",
         *     method: "",
         * }
         */
        return Promise.resolve(addressOptions);
    })
    .then(addressOptions => Promise.all(addressOptions.map(address => rp(address))))
    .then((arrayOfResolvedData) => {
        /*
         * arrayOfResolvedData is an Array of data per whatever rp() returns
         * probably Response Objects
         */
        console.log(arrayOfResolvedData);
    })
zero298
  • 25,467
  • 10
  • 75
  • 100
  • Please seem comment on the question : the requests are getting fired before I run the Promise.all code. – Dae Aug 01 '17 at 18:59
1

You could do what zero298 suggested in his edit.

the main problem is that you map your data to an actual promise, rather than something that is ready to execute a promise,

compare

Let promises = Options.map(option => execute(option))
Promise.all(promises)

With

Let promiseGenerators =Options.map(option => () => execute(option))
Promise.all(promiseGenerators.map(generator => generator())

The second you call the function that will return the promise, it will start doing it. That's where the problem was, because you called rp(options) too soon.

Jusmpty
  • 171
  • 1
  • 8