JavaScript 中的 Promise.all:如何获得所有承诺的解析值?

Posted

技术标签:

【中文标题】JavaScript 中的 Promise.all:如何获得所有承诺的解析值?【英文标题】:Promise.all in JavaScript: How to get resolve value for all promises? 【发布时间】:2017-03-31 07:34:36 【问题描述】:

我编写了以下 node.js 文件:

var csv = require('csv-parser');
var fs = require('fs')
var Promise = require('bluebird');
var filename = "devices.csv";
var devices;

Promise.all(read_csv_file("devices.csv"), read_csv_file("bugs.csv")).then(function(result) 
    console.log(result);
);


function read_csv_file(filename) 
    return new Promise(function (resolve, reject) 
            var result = []
            fs.createReadStream(filename)
                .pipe(csv())
                .on('data', function (data) 
                    result.push(data)
                ).on('end', function () 
                resolve(result);
            );
    )

如您所见,我使用Promise.all 来等待读取 csv 文件的两个操作。我不明白为什么,但是当我运行代码时,'console.log(result)' 行没有被提交。

我的第二个问题是我希望Promise.all.then() 的回调函数接受两个不同的变量,而每个变量都是相关承诺的结果。

【问题讨论】:

【参考方案1】:

第一个问题

Promise.all 接受一系列承诺

变化:

Promise.all(read_csv_file("devices.csv"), read_csv_file("bugs.csv"))

到(在参数周围添加[]

Promise.all([read_csv_file("devices.csv"), read_csv_file("bugs.csv")])
// ---------^-------------------------------------------------------^

第二个问题

Promise.all 为您传递给它的每个 Promise 解析一组结果。

这意味着您可以将结果提取到变量中,例如:

Promise.all([read_csv_file("devices.csv"), read_csv_file("bugs.csv")])
  .then(function(results) 
    var first = results[0];  // contents of the first csv file
    var second = results[1]; // contents of the second csv file
  );

您可以使用 ES6+ destructuring 进一步简化代码:

Promise.all([read_csv_file("devices.csv"), read_csv_file("bugs.csv")])
  .then(function([first, second]) 

  );

【讨论】:

谢谢。我的第二个问题呢?现在,结果包括两个文件中的所有数据。如何将每个文件的数据放到一个单独的数组中?【参考方案2】:

回答你的第二个问题:

如果您希望then 回调接受两个不同的参数,那么您可以使用Bluebird 及其spread 方法。见:

http://bluebirdjs.com/docs/api/spread.html

代替.then(function (array) ... ) 并且必须在then 处理程序中访问array[0]array[1],您将能够使用spread(function (value1, value2) ... ) 并根据需要命名这两个变量。

这是 Bluebird 的一个功能,普通的Promise 是不可能的。

你像 Promise 一样使用 Bluebird,例如:

var P = require('bluebird');
// and in your code:
return new P(function (resolve, reject)  ...
// instead of:
return new Promise(function (resolve, reject)  ...

当然,您不必将其命名为 P,但您可以随意命名。

有关更多示例,请参阅Bluebird Cheatsheets。

【讨论】:

谢谢。没有蓝鸟就没有办法吗? @CrazySynthax 没有。标准的 Promise 只有 then,它获取 Promise.all 的数组。 如果我使用'spread',如何提交错误处理?我在链接中没有看到 catch 子句。 @CrazySynthax 你使用.spread(...).catch(...) 就像你使用.then(...).catch(...) 一样。 @CrazySynthax 见Bluebird cheatsheet

以上是关于JavaScript 中的 Promise.all:如何获得所有承诺的解析值?的主要内容,如果未能解决你的问题,请参考以下文章

javascript 迭代数组,知道什么时候完成promise所有promise.all

Javascript 像 Java 8 上的“Promise.all”(可能带有 lambdas)

JavaScript Promise.all - 如何检查解析状态?

javascript Promise.all示例

javascript 合并Promise.all的结果

[万字详解]JavaScript 中的异步模式及 Promise 使用