In the Bluebird Promise FAQ, .then(success, fail) is flagged as an antipattern. This can be confusing, especially if you don't understand the explanation regarding try and catch statements.
The .then() call returns a promise that rejects if the callback throws an error. This means if the success logger fails, the error would be passed to the following .catch() callback, not the fail callback accompanying success.
The control flow for .then with two arguments and .then-catch chain is illustrated below:
[Image of control flow diagrams for .then and .then-catch chain]
To express this in synchronous code:
// some_promise_call().then(logger.log, logger.log) then: { try { var results = some_call(); } catch(e) { logger.log(e); break then; } // else logger.log(results); }
Compare this with:
// some_promise_call().then(logger.log).catch(logger.log) try { var results = some_call(); logger.log(results); } catch(e) { logger.log(e); }
In this case, the catch logger handles exceptions from the success logger call.
The argument against this pattern is that you should generally catch errors in every processing step and avoid using it in chains. The expectation is that you have only one final handler for all errors.
However, this pattern is helpful when handling specific errors in a particular step and taking a different action if no error occurs. Be aware that this branches your control flow.
Consider the following:
some_promise_call() .catch(function(e) { return e; // it's OK, we'll just log it }) .done(function(res) { logger.log(res); });
Alternatively, you could use .finally() for this purpose.
The above is the detailed content of When is Using `.then(success, fail)` an Antipattern in Promises?. For more information, please follow other related articles on the PHP Chinese website!