2

I am new to javascript. I have an array of promises that are for asynchronous Ajax calls using $.getJSON. The number of promises can vary. So to resolve them, I am using

$.when.apply($, promises).done(function(data) {

I am doing .apply because I don't know how many promises there are, so I give it an array of promises instead. The problem I am having is the data variable only returns data for the first promise. If I had two promises, I could do this

$.when.apply($, promises).done(function(firstData, secondData) {

But because the number of promises is unknown, I cannot setup the right arguments for the callback function in .done(). I want to get an array containing the resolved data for each Ajax call in the .done() callback if that is possible

Phil
  • 157,677
  • 23
  • 242
  • 245
JoeChris
  • 231
  • 1
  • 9
  • [`$.when` is weird](https://stackoverflow.com/a/21376219/1048572). Don't use it any more, just go for `Promise.all`. – Bergi Jul 29 '21 at 00:05

1 Answers1

4

This is where spread syntax can come in handy.

Try something like this

$.when(...promises).done((...results) => {
  // results is an array
})

This works by

  1. Treating the promises array like individual function arguments

    $.when(promises[0], promises[1], ..., promises[promises.length - 1])
    
  2. Combining the individual arguments for the .done() callback function into an array


For completeness, this is really one of those situations where you might not need jQuery. Modern browsers support Fetch and Promise.all as very good vanilla JS replacements for $.when and $.ajax

const getJson = async (url) => {
  const res = await fetch(url)
  if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`)
  return res.json()
}

Promise.all([ getJson(url1), getJson(url2) ]).then(results => {
  // results is an array
})

If you're one of those poor, unfortunate souls who still have to support Internet Exploder Explorer, you can use apply() and the arguments object

$.when.apply($, promises).done(function() {
  var results = arguments
})
Phil
  • 157,677
  • 23
  • 242
  • 245
  • 1
    if you are in an environment without spread syntax (in other words, Internet Explorer) then you'd use the *array-like* `arguments` in the function to access all the arguments – Bravo Jul 28 '21 at 23:16
  • @Bravo true. Would need to stick with `apply` for the `.when()` part. I'll add that in – Phil Jul 28 '21 at 23:17
  • it is working in all the ways now. I will stick to arguments object because I do have to support ie ): Thank you for your help – JoeChris Jul 28 '21 at 23:24
  • 1
    @JoeChris _"I do have to support ie"_... I'm so sorry. Take heart that IE 11 only has one more year of official support left (till June 2022) – Phil Jul 28 '21 at 23:27