How to create an array of uncalled promise functions

188 views Asked by At

My problem is I cannot construct the promisesArray.

This works perfectly but I need to construct this array on the fly.

var promisesArray=[get(url1),get(url2),get(url3)];  // url1,url2,url3 are valid urls here

var promises = Promise.all(promisesArray);

promises.then(function(results) {
 console.log('this came back: ',results);
}).catch(function(error) {
  console.log(error);
});;

function get(url) {
  // Return a new promise.
  return new Promise(function(resolve, reject) {
    // Do the usual XMLHttpRequest stuff

  });
}

I am trying to build the array promisesArray above, where each element is a promise, but every way I try I am only adding the result of calling get() and I end up with an array of pending promises

Array [ Promise { "pending" }, Promise { "pending" }, Promise { "pending" }]

When I want:

promisesArray=[get(url1),get(url2),get(url3)];

For example, I have tried:

let template=['a','b','c','d'];

  var promiseArray=[]
  template.forEach(function(pos){
      let url=lookupUrl[pos]]();  //just a function that returns a Url determined by the values of template array
          promiseArray.push(get(url));
  })

but obviously I am only returning the result of the get call here..

I tried using bind, but once again I end up with an array of executing promises...

 var promiseArray = template.map(function(pos){
   var url = lookupUrl[pos]]();
   var out= get.bind(null,url);
   return out()
 })

I don't know how to create an array of uncalled functions.

[EDIT_UPDATE] As @JaromandaX pointed out in the first comment I already had what I needed, and in fact either of the above two methods work for building the array of promises. As @Roamer-1888 also pointed out, I got side tracked into thinking that I needed an array of 'uncalled functions' which was not true.

I like the method used by @HMR in his answer so I am going to try that.

2

There are 2 answers

0
HMR On BEST ANSWER

I think you're looking for map:

Promise.all(
  urls.map(get)
)

If you have an array of template then map those to url and then url to promise:

const template=['a','b','c','d'];

Promise.all(
  template.map(//map pos to url
    pos=>lookupUrl[pos]()
  ).map(//map url to promise
    get
  )
);

If you need to throttle it somehow then have a look at this answer.

0
Joshua R. On

Why don't you build you array of functions that return the get-promise and then defer execution until you're inside promise.all?

var promisesArray=[()=>get(url1),()=>get(url2),()=>get(url3)];

promise.all(promisesArray.map((x)=>x()))

This will kick-off all of your get requests at the same time and all's promise won't resolve until they're all done.