当你想要所有结果而不管是否被拒绝时,用什么代替Promise.all()

What to use instead of Promise.all() when you want all results regardless of any rejections

本文关键字:什么 Promise all 拒绝 结果 是否 不管 当你      更新时间:2023-09-26

我正在node.js项目中使用Bluebird promise库。我有两个操作都会返回promise,我想知道这两个操作何时完成,是已解决还是已拒绝,我需要两者的返回值。我正在读取多个文件的内容,其中一些文件可能不存在,这是一个正常条件,因此,尽管如果文件不存在,fs.readFileAsync()将失败,但我仍然需要其他读取操作的结果。

如果p1或p2拒绝,Promise.all(p1, p2)将拒绝,并且我认为我不一定会从另一个获得数据。

在所有其他Bluebird操作(.some().any().settle()等)中,哪种操作最适合这种情况?而且,数据是如何传递回来的,这样你就可以判断哪些成功了,哪些没有成功?

那确实是.settle。Settle接受一系列promise,并在它们解析时返回所有promise的PromiseInspection实例。然后,您可以检查它们是满足还是被拒绝,并提取它们的价值。

例如:

Promise.settle(['a.txt', 'b.txt'].map(fs.readFileAsync)).then(function(results){
    // results is a PromiseInspetion array
    console.log(results[0].isFulfilled()); // returns true if was successful
    console.log(results[0].value()); // the promise's return value
});

您的用例几乎就是Promise.settle存在的目的。

只有尝试不同的选项,然后最终在调试器中执行代码,我才知道如何使用.settle():

// display log files
app.get('/logs', function(req, res) {
    var p1 = fs.readFileAsync("/home/pi/logs/fan-control.log");
    var p2 = fs.readFileAsync("/home/pi/logs/fan-control.err");
    Promise.settle([p1, p2]).spread(function(logFile, errFile) {
        var templateData = {logData: "", errData: ""};
        if (logFile.isFulfilled()) {
            templateData.logData = logFile.value();
        }
        if (errFile.isFulfilled()) {
            templateData.errData = errFile.value();
        }
        res.render('logs', templateData);
    }).catch(function(e) {
        console.log("err getting log files");
        // figure out what to display here
        res.render(e);
    });
});

如果蓝鸟团队的任何人来了,关于如何使用.settle()的文档缺少了理解如何使用它所需的大约2/3。它引用了PromiseInspection,但没有提及如何使用它。文档中关于.settle()以及如何检查.settle()返回的结果的简单代码示例将节省数小时的时间。