May 1st, 2016

Last week I learned...

...that a JavaScript promise chain with a rejected promise will behave differently depending on the number of arguments provided to the then method.

Consider the following two cases:

1) The then method of the rejected promise receives only one function as an argument

1  const a = Promise.reject('I was rejected')

2  a.then(message => console.log(message))
3    .then(message => console.log(message))
4    .catch(message => console.log('catch', message))


The promise on line 2 gets rejected, but its then method has only one argument, which is a callback for cases when the promise is successfully resolved. This callback does not get called; instead the error is passed to the next promise. Consequently, the rest of the promise chain will not get called either, and the error will propagate towards the catch block.

2) Now a similar case, but this time the then method of the rejected promise is supplied with two functions as arguments

1  const a = Promise.reject('I was rejected')
2  const happyCallback = () => console.log('hooray!')
3  const sadCallback = () => console.log('bummer!')

4  a.then(happyCallback, sadCallback)
5    .then(happyCallback, sadCallback)
6    .then(() => console.log('i passed the rejected promise!') )


This time the rejected promise on line 4 is passed two callbacks — first one for successful resolution of the promise, and the second one for taking care of the error. The error is handled by the second callback, and the promise chain happily continues to promises on lines 5 and 6. The console will output first "bummer" (from the second callback on line 4), then "hooray!" (from the first callback on line 5), then "i passed the rejected promise!" from the callback on line 6.

The fact that the presence of the second callback will keep the promise chain running took me by complete surprise. I was under the impression that the `catch` syntax for promises is just syntactic sugar for the second callback to the `then` method.

(also, I realized that it's easier to write all this stuff in English without any attempt to translate or transcribe web dev jargon into Russian)