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

混江龙づ霸主 提交于 2019-12-10 11:23:53

问题


I'm using the Bluebird promise library in a node.js project. I have two operations that both return promises and I want to know when both are done, whether resolved or rejected and I need the return values from both. I'm reading the contents of multiple files and some of the files may not exist and that's an OK condition, so though fs.readFileAsync() will fail if the file doesn't exist, I still need the results of the other read operation.

Promise.all(p1, p2) will reject if either p1 or p2 rejects and I don't think I'll necessarily get the data from the other one.

Of all the other Bluebird operations (.some(), .any(), .settle(), etc...) which is most appropriate to this situation? And, how is the data passed back such that you can tell which ones succeeded and which ones didn't?


回答1:


That would be indeed be .settle. Settle takes an array of promises and returns PromiseInspection instances for all of them when they resolve. You can then check if they're fulfilled or rejected and extract their value.

For example:

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
});

Your use case is pretty much what Promise.settle exists for.




回答2:


Only by trying different options and then ultimately stepping through code in the debugger, I figured out how to do this using .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);
    });
});

If anyone from the Bluebird team comes along, the doc for how to use .settle() is missing about 2/3 of what is needed to understand how to use it. It makes reference to a PromiseInspection, but makes no reference on how to use that. A simple code example in the doc for .settle() and for how you examine the results that .settle() returns would have saved hours of time.



来源:https://stackoverflow.com/questions/25965977/what-to-use-instead-of-promise-all-when-you-want-all-results-regardless-of-any

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!