【问题标题】:Execute an array of promises when it is ready准备好时执行一系列承诺
【发布时间】:2018-04-28 21:13:03
【问题描述】:

如何让 Promise 仅在连接完成后才执行?

var fs = require('fs');
var testFolder = './lib/';
var files = ['hello.txt', 'goodbye.txt'];
var contents = '';
//creating array of promises
let promises = files.map(async e => {
    return await fs.readFile(testFolder + e, "utf8", function (err, content) {
            contents += content + ".\n";
        });
 }
);
    console.log(promises);
    //this should happen last but "contents" is still empty string?
    Promise.all(promises).then(()=> console.log(contents));

【问题讨论】:

  • 最终字符串的顺序重要吗?

标签: javascript node.js promise fs


【解决方案1】:

fs.readFile 不返回承诺。

您应该使用util.promisify 来实现它。

此外,正如 Patrick Hübl-Neschkudla 在下面的评论中所提到的,没有必要使用 async/await,因为 readFile 现在已经返回了一个承诺,我们直到稍后才会处理结果。

Bergi 在 cmets 中还指出,fs.readFile 回调不能保证按创建顺序返回。事实上,大多数fs 操作都是这种情况,因为其他进程总是可以通过同时操作文件来干扰您的操作——例如,如果有人写入您要读取的文件怎么办?

您应该在所有读取完成后执行连接,而不是在它们发生时执行连接(因为它们可能会不同步)。

这也将确保all rejections are properly caught 无论哪个承诺(文件读取)失败。

const readFile = util.promisify(fs.readFile);

Promise.all(
  files.map(e => readFile(testFolder + e, "utf8"))
)
.then(contentArray => contentArray.join('.\n'))
.then(console.log);

【讨论】:

  • 这里不需要异步/等待
  • 您应该提到这在结果字符串中没有contents 的确定顺序。
  • @Bergi 你是说我应该提一下fs.readFile 回调不能保证按创建顺序返回?
  • @nem035 是的,人们可能会从 Promise 中期待这一点。应该在Promise.all 之后简单地进行连接
  • @Bergi 有道理,我会删除这些建议。
猜你喜欢
  • 2016-02-01
  • 2016-12-30
  • 2013-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
  • 1970-01-01
  • 2017-07-05
相关资源
最近更新 更多