1

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.

user2250892
  • 126
  • 1
  • 9
  • 3
    so, you want an array of promises, not an array of promises? – Jaromanda X Feb 12 '18 at 04:04
  • when/how will the `get` be started? I mean, you could do `function get(url) { return function() { // Return a new promise. return new Promise(function(resolve, reject) { // Do the usual XMLHttpRequest stuff }); }; }` ... then you have an array of functions, but how will they be called? – Jaromanda X Feb 12 '18 at 04:06
  • I'm sorry I don't understand your question. I need the array as in the first section of code that works, where I typed into my program the array of promises.. I can't build it programatically. – user2250892 Feb 12 '18 at 04:06
  • so, you want your array to be an array of Promises? – Jaromanda X Feb 12 '18 at 04:08
  • I guess the Promise.all function calls them – user2250892 Feb 12 '18 at 04:08
  • No, Promise.all waits for their completion – Jaromanda X Feb 12 '18 at 04:08
  • @JaromandaX . Yes an array of uncalled functions that are then called by the Promise.all – user2250892 Feb 12 '18 at 04:09
  • 1
    Promise.all does not call functions, it waits for Promises to resolve – Jaromanda X Feb 12 '18 at 04:09
  • What problem are you having with the overall code in the first snippet? Does `console.log('this came back: ',results);` output something you didn't expect? – Jaromanda X Feb 12 '18 at 04:10
  • @JaromandaX..ok I see...obviously more here that I don't understand than I thought.. – user2250892 Feb 12 '18 at 04:11
  • @JaromandaX.. the first code snippet works but I need to generate lots of these arrays dynamically – user2250892 Feb 12 '18 at 04:12
  • then do so, there's nothing wrong with that code at all – Jaromanda X Feb 12 '18 at 04:12
  • `let url=lookupUrl[pos]]();` - have you verified that this returns the expected url? – FuzzyTree Feb 12 '18 at 04:13
  • @JaromandaX.. you are right.. I get it, I didn't understand what the Promise.all was doing, I thought it was actually calling the functions. Thanks – user2250892 Feb 12 '18 at 04:18
  • So @JaromandaX, what I don't understand now is how were the get(url) functions inside the array called in my first snippet?.. – user2250892 Feb 12 '18 at 04:24
  • didn't you say you had an array of promises? – Jaromanda X Feb 12 '18 at 04:49
  • yes the first line of the first snippet, but I didn't think the functions inside the array would be called just by declaring the var promisesArray – user2250892 Feb 12 '18 at 04:51
  • You function gets called in the Promise constructor. Its *executor* parameter is called immediately. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise So as soon as you call (`()`) your `get` function , the `// Do the usual XMLHttpRequest stuff` will get called. – Kaiido Feb 12 '18 at 04:51
  • "but obviously I am only returning the result of the get call here", yes and that's precisely what you want, or at least what you initially asked for before you got side-tracked into "array of uncalled functions". – Roamer-1888 Feb 12 '18 at 10:37

2 Answers2

0

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.

Joshua R.
  • 2,282
  • 1
  • 18
  • 21
0

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.

HMR
  • 37,593
  • 24
  • 91
  • 160