2

I have a multidimensional array of promises that I'm trying to resolve. If I console.log the result I can view the arrays and within each one is the promise along with a [[PromiseStatus]] and a [[PromiseValue]]. How do I get the promise value?

Here's a snippet of code:

(resourcePromises is just a multidimensional array of promises).

    Promise.all(resourcePromises).then(function(values)
    {
        console.log(values);
    });

And then the variable values will hold multiple arrays, and within each of those arrays is a list of promises that I'm trying to grab the values from.

user1157885
  • 1,999
  • 3
  • 23
  • 38
  • What should the expected output be in values? Should it also be a multidimensional array with resolved promise values? – Matthijs Apr 09 '16 at 14:24
  • Possible duplicate of [How to do promise.all for array of array of promises?](http://stackoverflow.com/questions/36094865/how-to-do-promise-all-for-array-of-array-of-promises) – sheilak Apr 09 '16 at 14:27

4 Answers4

3

Sounds like you need to run Promise.all at the deepest level, then the next deepest, and so on until you reach the top. For 2D arrays, that would be:

Promise.all(promises.map(Promise.all)).then(function(values) {
    console.log(values);
});

If you want to go to arbitrary depths then you would need to choose between map and all for each level:

function deepAll(array) {
    if (array instanceof Promise)
        // Just in case...
        return array;
    else if (array.length == 0)
        // The 'real' function will fail with an empty array and it's the same in both cases anyhow.
        return [];
    else if (Array.isArray(array[0]))
        // There's another array level, so turn it into an array of promises.
        return array.map(deepAll);
    else
        // This is an array of promises, and we already have a function for that case.
        return Promise.all(array);
}

deepAll(promises).then(function(values) {
    console.log(values);
});
Andrew Taylor
  • 682
  • 4
  • 8
  • 1
    I would use `array.length === 0` to avoid triggering on `undefined`, or check type before looking at `length`, otherwise this `if` may trigger on plain values. Also, I would [check for a `.then` method](http://stackoverflow.com/q/27746304/918910) rather than use `instanceof` which is unreliable. – jib Apr 09 '16 at 21:21
1

Promise.all takes iterable as it's argument. So you just need to write an iterator which walks throw your multidimensional array

 function *deepWalk(arr) {
   for (var item of arr) {    
     if (Array.isArray(item))
       yield* deepWalk(item)
     else
       yield item;
   }
 }

 Promise.all(deepWalk(resourcePromises)).then(...
Nick Rassadin
  • 860
  • 7
  • 7
0

Use this snippet for subarrays:

const balancePromises = [...];
const symbolPromises = [...];

const [balances, symbols] = await Promise.all([
    Promise.all(balancePromises),
    Promise.all(symbolPromises)
]);
k06a
  • 17,755
  • 10
  • 70
  • 110
0

The answer above from Andrew Taylor works well. It took me a little while to figure out how to implement it for a particular 2d array, so I wanted to show how I did it for learning more about Promise.all:

// This function will iterate over a 2d array of IDs to load async data
// based on each ID and resolve all of the promises before proceeding.
const getAsyncData = async (outerArray) => {
  const data = await Promise.all(
    outerArray.map(async innerArray => await Promise.all(
        innerArray.map(async id => await mockGettingDataFromServer(id))
    ))
  )

  return data;
}

// This function will simulate getting data from the IDs asynchronously
function mockGettingDataFromServer(id) {
  return new Promise((resolve, reject) => {
     window.setTimeout(() => {
       resolve(`Resolved ${id}`)
     }, 10)
  });
}

// A 2d array of IDs
const ids = [['ID1', 'ID2', 'ID3'], ['ID1', 'ID4'], ['ID2', 'ID3', 'ID5']];

// Pass the 2d array of IDs to the getAsyncData function to get an
// array of arrays of resolved promises, e.g. data from the server
const myData = getAsyncData(ids);

console.log(myData); // [["Resolved ID1", etc], [...], [...]]


adam Kiryk
  • 1,735
  • 2
  • 14
  • 14