【发布时间】:2017-06-25 11:43:49
【问题描述】:
我想下载很多图片(1000+),所以我将数组拆分成指定大小的块并一个接一个地下载。下载是基于承诺的,一旦一个块完成就解决。如果不使用块,一切正常,但使用此实现会发生以下情况:
console.log("Promise Recursive resolved", paths);
在下载递归函数完成后被调用,但它没有按预期解析,所以
console.log("Finished");
不会在 downloadAll 函数中调用。
function downloadAll(folder, full_size, images) {
return new Promise(function (resolve, reject) {
// Chunks of all images [ [1,2,3,4,5], [6,7,8,9,10], [...] ]
let grouped_images = chunk(images, 5);
downloadRecursive(folder, full_size, grouped_images, 1, []).then(function (e) {
console.log("Finished");
resolve(e);
}).catch(function () {
reject();
});
});
}
function downloadRecursive(folder, full_size, all, part, paths) {
return new Promise(function (resolve, reject) {
if(part > all.length){
console.log("Promise Recursive resolved", paths);
resolve(paths);
}
downloadImages(folder, all[part-1], full_size).then(function (e) {
paths.push(e);
return downloadRecursive(folder, full_size, all, part+1, paths);
});
});
}
function downloadImages(folder, images, full_size=true) {
[...]
return Promise.all(images.map(function (image) {
[...]
return doDownload(...);
}));
}
function doDownload(url, path, full_size){
returns promise
}
【问题讨论】:
-
您可能会发现 Bluebird 的
Promise.map()及其并发选项非常有用。它解决了这样的问题。如何同时运行不超过 N 的大量异步操作。 -
像这样创建新的 Promise 是一种反模式。而不是执行“
new Promise(...)...”然后从.then和.catch调用resolve/reject 放弃new Promise并返回您的承诺链。见:jf.io/2016/10/09/… -
我同意上面的,问题可能是你在
downloadRecursive中调用resolve后没有返回,所以它会额外运行downloadImages,可能会失败. -
在 downloadRecursive 中,除非
(part > all.length),否则前提永远不会被解决或拒绝 - 所以,你会有“待定”的承诺 -
Promise.map()看起来不错。我会调查的,谢谢。
标签: javascript node.js recursion ecmascript-6 promise