如何遍历node.js中的promises数组?

时间:2017-02-01 15:14:34

标签: javascript arrays node.js asynchronous promise

在javascript中,我有一个非平坦的Promises数组:

const array = [
  [ promise11, promise12.. promise1n ],
  [ promise21, promise22.. promise2n ],
  [ promise31, promise32.. promise3n ],
  ...  
  [ promisek1, promisek2.. promisekn ]
];

如何以这种方式遍历数组,其中下一个promises数组将在前一个promise数组解析后才开始解析?例如,我希望脚本等到[ promise11, promise12.. promise1n ] promises并行解析,然后再调用下一个promises数组。

我正在寻找一个通用的解决方案,因为我的应用程序无法事先知道它必须进行多少次调用(它是一个webscrapper)。

1 个答案:

答案 0 :(得分:3)

可以使用Array#reduce模式的变体:

array.reduce(
    (p, subArray) => p.then(() => Promise.all(subArray)),
    Promise.resolve()
);

设置一个promise链,其中链中的每个条目都是Promise.all对数组中子数组的承诺的结果。

...但:

  

...下一个承诺数组只会在上一个承诺数组解决后开始解决?

这不是承诺如何运作的。一旦你有了承诺,它承诺的结果就是已经正在进行中。你没有开始"它

所以反而,你想让array一系列函数启动相关流程并返回承诺,这是一点点不同:



function get(label) {
  console.log(label + "- starting");
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(label + "- resolving");
      resolve(label);
    }, Math.random() * 500);
  });
}
const array = [
  [ get.bind(null, "1a"), get.bind(null, "1b"), get.bind(null, "1c") ],
  [ get.bind(null, "2a"), get.bind(null, "2b") ],
  [ get.bind(null, "3a"), get.bind(null, "3b"), get.bind(null, "3c"), get.bind(null, "3d") ]
];

array.reduce(
  (p, subArray) => p.then(() => Promise.all(subArray.map(f => f()))),
  Promise.resolve()
).then(() => {
  console.log("All done");
});

.as-console-wrapper {
  max-height: 100% !important;
}




注意数组现在是一个函数数组,当被调用时#34; start"过程然后返回一个承诺。我们的Array#reduce循环只是略有修改:我们使用Array#map来调用此子数组的函数并获取其承诺的数组,这是我们提供给Promise.all的内容。因此,调用给定子数组的所有函数以启动该子数组的工作,然后我们等待它们全部完成,然后继续下一个子数组并开始工作。