javascript - 如何遍历 node.js 中的一系列 promise ?

标签 javascript arrays node.js asynchronous promise

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

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

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

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

最佳答案

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

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

这建立了一个 promise 链,其中链中的每个条目都是 Promise.all 对数组中的子数组的 promise 的结果。

...但是:

...where the next array of promises would start resolving ONLY after the previous array of promises have resolved?

这不是 promise 的工作方式。获得 promise 后,它 promise 结果的操作已经在进行中。您不会“启动”它。

因此,相反,您希望将 array 设为启动相关进程并返回 promises 的函数数组,即略有不同:

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

注意这个数组现在是一个函数数组,当它被调用时“启动”进程然后返回一个 promise 。我们的 Array#reduce 循环仅稍作修改:我们使用 Array#map 调用此子数组的函数并获取它们的 promise 数组,这就是我们输入的内容Promise.all。因此,调用给定子数组的所有函数以开始该子数组的工作,然后我们等到它们全部完成,然后继续下一个子数组并让它开始工作。

关于javascript - 如何遍历 node.js 中的一系列 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41983202/

相关文章:

c - 结构数组与结构指针之间的表达式相等

java - 递归调用溢出堆栈

javascript - 从 node.js 中的变量解析 CSV 表

node.js - Angular 和 Express - 文件结构

javascript - Asp.Net Mvc - ContentPlaceHolder- Javascript

javascript - 检测用户是否来自您的网站

javascript - ChartJS 根据下拉选择更改图表

javascript - Puppeteer.launch 取决于操作系统

java - Do - 在用户输入正确或不正确的参数后,While 循环不会继续

node.js - npm scripts 两个破折号是什么意思?