在javascript中,我有一个非平坦的Promises数组:
const array = [
[ promise11, promise12.. promise1n ],
[ promise21, promise22.. promise2n ],
[ promise31, promise32.. promise3n ],
...
[ promisek1, promisek2.. promisekn ]
];
如何以这种方式遍历数组,其中下一个promises数组将在前一个promise数组解析后才开始解析?例如,我希望脚本等到[ promise11, promise12.. promise1n ]
promises并行解析,然后再调用下一个promises数组。
我正在寻找一个通用的解决方案,因为我的应用程序无法事先知道它必须进行多少次调用(它是一个webscrapper)。
答案 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
的内容。因此,调用给定子数组的所有函数以启动该子数组的工作,然后我们等待它们全部完成,然后继续下一个子数组并开始工作。