I use ES6 promises (and not the async / await pattern). Promises were the promise to avoid the Christmas tree problem of nested callbacks. Consider three API calls. Using promises, the code will look like so.
const promiseA = Promise.resolve(42); const promiseB = Promise.resolve(87); const promiseC = Promise.resolve(111); promiseA .then(r => promiseB) .then(r => promiseC) .then(() => {});
It looks pretty neat. To make it a bit concrete, let us say, Promise A checks if an user exists, Promise B inserts a new user, Promise C does something using the user record. If the user does not exist, we call Promise B. If the user already exists, we call Promise C directly. This is what I call the conditional Promise Chaining pattern.
A simple if condition after Promise A makes us think that the code is complex. Here is a first cut of how I wrote my code.
function testConditionalPromise(isCondition) { const promiseA = Promise.resolve(42); const promiseB = Promise.resolve(87); const promiseC = Promise.resolve(111); promiseA .then(r => { if (isCondition) { return promiseB .then(() => promiseC); } else { return promiseC; } }) .then(() => {}); } testConditionalPromise(true); testConditionalPromise(false);
The above code works fine. But it looks ugly. The if-condition introduces another level of nesting which we want to avoid while writing Promise based code. So, for a JavaScript purist, I recommend the following code.
See the Pen Conditional Promise Pattern by Vijay Thirugnanam (@vijayst) on CodePen.0
The solution is to process Promise B in the second then
and Promise C in the third then
. If Promise C appears in the second then
, just pass it along to the next block. Conditional Promise Chaining done this way is neat as it avoids nesting. Just a little bit to keep your code clean.
Such a simple explanation, thank you Mr. Thirugnanam