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?
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.
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.