node.js使用promises递归下载chunked数组

时间:2017-02-08 01:45:46

标签: javascript node.js recursion ecmascript-6 promise

我想下载大量图片(1000+),因此我将Array拆分为指定大小的块并一个接一个地下载。下载是基于承诺的,并在块完成后解决。不使用块一切正常,但是通过这种实现,会发生以下情况:

console.log("Promise Recursive resolved", paths);

一旦完成就会在downloadRecursive函数中调用,但它没有按预期解析,所以

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
}

2 个答案:

答案 0 :(得分:0)

请尝试使用array#reduce,而不是使用递归调用

function downloadAll(folder, full_size, images) {
    return chunk(images, 5)
    .reduce((promsie, chunk) => 
        promise.then((array) => 
            downloadImages(folder, chunk, full_size)
            .then(result => 
                array.concat(result)
            )
        ), Promise.resolve([])
    );
}


function downloadImages(folder, images, full_size=true) {
    [...]
    return Promise.all(images.map(function (image) {
        [...]
        return doDownload(...);
    }));
}

function doDownload(url, path, full_size){
    returns promise
}

答案 1 :(得分:0)

你需要抓住并找出打破链条的错误,这样你就可以调试一路上发生的事情:

    before_filter :find_comment, :only => [:destroy]

    def destroy
      @comment.destroy
    end

    def find_comment
      @comment = Comment.get(params[:id])
    end

    private

    def comments_params
      params.required(:comment).permit(:author,:body)
    end

最糟糕的情况是,如果你不能避免1000多个图像中的一些错误,那么你可能想要在有问题的代码中添加一个catch()块,并且只是抑制错误并允许循环继续。