【问题标题】:Getting the results of a promise in a multidimensional array在多维数组中获取承诺的结果
【发布时间】:2016-07-30 19:05:45
【问题描述】:

我有一个要解决的多维承诺数组。如果我控制台记录结果,我可以查看数组,并且在每个数组中都有承诺以及 [[PromiseStatus]] 和 [[PromiseValue]]。如何获得承诺值?

这是一段代码:

(resourcePromises 只是一个多维的 promise 数组)。

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

然后变量值将包含多个数组,在每个数组中都有一个我试图从中获取值的承诺列表。

【问题讨论】:

标签: javascript arrays multidimensional-array promise


【解决方案1】:

听起来您需要在最深的级别运行Promise.all,然后是下一个最深的级别,依此类推,直到您到达顶部。对于二维数组,这将是:

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

如果您想进入任意深度,则需要在每个级别的mapall 之间进行选择:

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);
});

【讨论】:

  • 我会使用array.length === 0 来避免触发undefined,或者在查看length 之前检查类型,否则这个if 可能会触发纯值。另外,我会check for a .then method 而不是使用不可靠的instanceof
【解决方案2】:

Promise.alliterable 作为它的参数。所以你只需要编写一个迭代器来遍历你的多维数组

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

 Promise.all(deepWalk(resourcePromises)).then(...

【讨论】:

    【解决方案3】:

    将此 sn-p 用于子数组:

    const balancePromises = [...];
    const symbolPromises = [...];
    
    const [balances, symbols] = await Promise.all([
        Promise.all(balancePromises),
        Promise.all(symbolPromises)
    ]);
    

    【讨论】:

      【解决方案4】:

      Andrew Taylor 的上述回答效果很好。我花了一点时间才弄清楚如何为特定的 2d 数组实现它,所以我想展示我是如何做到的,以了解更多关于 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], [...], [...]]
      
      
      

      【讨论】:

        猜你喜欢
        • 2017-10-18
        • 1970-01-01
        • 1970-01-01
        • 2017-12-14
        • 2021-03-15
        • 2016-11-12
        • 2016-09-17
        • 2016-12-22
        • 2021-02-18
        相关资源
        最近更新 更多