Why are both Promise calls and callback traps called?

I have the following code, and when it is executed, it returns both β€œ rejected ” and β€œ success ”:

// javascript promise var promise = new Promise(function(resolve, reject){ setTimeout(function(){reject()}, 1000) }); promise .catch(function(){console.log('rejected')}) .then(function(){console.log('success')}); 

Can anyone explain why success is being recorded?

+7
javascript ecmascript-6 es6-promise
source share
2 answers

The then callback is called because the catch callback occurs before it, and not after. The failure has already been handled by catch . If you change the order (i.e. ( promise.then(...).catch(...) )), then callback will fail.

MDN says the .catch() method returns a new promise that resolves the return value of the callback. "The catch callback does not return anything, so the promise is resolved with an undefined value.

+9
source share

Can anyone explain why success is being recorded?

In short: a .then after .catch in the Promise chain will always be executed (unless it itself contains errors).

Theoretical explanation

Your code is actually a Promise chain that runs synchronously at first, setting it to complete asynchronously after that. The Javascript engine will pass any reject() or Error to the first .then down the chain with a reject callback. The reject callback is the second function passed to .then :

 .then( function (){ //handle success }, function () { //handle reject() and Error }) 

Using .catch is just a syntactic suger for:

 .then(null, function () { //handle reject() or Error }) 

Each of .then automatically returns a new Promise , which can be affected by subsequent .then (or .catch , which are also .then 's).

Visualize your promise chain flow

You can visualize the flow of your code in the following example:

 var step1 = new Promise (function (resolve, reject) { setTimeout(reject('error in step1'), 1000); }) var step2 = step1.then(null, function () { // do some error handling return 'done handling errors' }) var step3 = step2.then(function () { // do some other stuff after error handling return 'done doing other stuff' }, null) setTimeout (function () { console.log ('step1: ', step1); console.log ('step2: ', step2); console.log ('step3: ', step3); console.log(); console.log ('Asynchronous code completed') console.log(); }, 2000); console.log ('step1: ', step1); console.log ('step2: ', step2); console.log ('step3: ', step3); console.log(); console.log ('Synchronous code completed') console.log(); 

which at runtime will lead to the following output in the console:

 step1: Promise { <rejected> 'error in step1' } step2: Promise { <pending> } step3: Promise { <pending> } Synchronous code completed step1: Promise { <rejected> 'error in step1' } step2: Promise { 'done handling errors' } step3: Promise { 'done doing other stuff' } Asynchronous code completed 
+8
source share

All Articles