如何使用 lodash、underscore 或 bluebird 同步迭代数组

How to iterate an array synchronously using lodash, underscore or bluebird

我有一个包含每个索引处的文件名的数组。我想一次下载这些文件 (同步)。我知道“Async”模块。但我想知道 LodashUnderscoreBluebird 库中的任何函数是否支持此功能。

您可以使用蓝鸟的 Promise.mapSeries:

var files = [
    'file1',
    'file2'
];

var result = Promise.mapSeries(files, function(file) {
    return downloadFile(file); // << the return must be a promise
});

根据您使用什么下载文件,您可能需要建立或不建立承诺。

更新 1

仅使用 nodejs 的 downloadFile() 函数示例:

var http = require('http');
var path = require('path');
var fs = require('fs');

function downloadFile(file) {
    console.time('downloaded in');
    var name = path.basename(file);

    return new Promise(function (resolve, reject) {
        http.get(file, function (res) {
            res.on('data', function (chunk) {
                fs.appendFileSync(name, chunk);
            });

            res.on('end', function () {
                console.timeEnd('downloaded in');
                resolve(name);
            });
        });
    });
}

更新 2

正如 Gorgi Kosev 所建议的,使用循环构建承诺链也很有效:

var p = Promise.resolve();
files.forEach(function(file) {
    p = p.then(downloadFile.bind(null, file));
});

p.then(_ => console.log('done'));

承诺链只会为您提供链中最后一个承诺的结果,而 mapSeries() 为您提供包含每个承诺结果的数组。

使用Bluebird,有一个类似你的情况,这里有一个答案: How to chain a variable number of promises in Q, in order?

这似乎是一个不错的解决方案,但在我看来,async.eachSeries 的可读性和优雅性要差得多(我知道你说过你不想要 'async' 解决方案,但也许你可以重新考虑。