3

JavaScript Promises: then(f,f) vs then(f).catch(f)

 3 years ago
source link: https://dmitripavlutin.com/javascript-promises-then-vs-then-catch/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

In JavaScript, you can check the status of the resolved promise using 2 approaches.

A) Use 2 callbacks on promise.then() — the first for fullfillment and the second for rejection:

promise
  .then(success, error);

B) Use a chain of promise.then().catch():

promise
  .then(success)
  .catch(error);

Is there any difference between the 2 approaches? Let’s find out!

1. What’s the same

Let’s consider the callbacks we’re going to use:

function success(value) {
  console.log('Resolved: ', value);
}

function error(err) {
  console.log('Error: ', err);
}

success() function would be called on fulfillments, while error() on rejections.

In most cases both approaches work the same way: if promise resolves successfully, then success is called in both approaches:

Promise.resolve('Hi!')
  .then(success, error);
// Logs 'Resolved: Hi!'

Promise.resolve('Hi!')
  .then(success)
  .catch(error);
// Logs 'Resolved: Hi!'

Try the demo.

Otherwise, in case of rejection, error callback is called:

Promise.reject('Oops!')
 .then(success, error);
// Logs 'Error: Oops!'

Promise.reject('Oops!')
 .then(success)
 .catch(error);
// Logs 'Error: Oops!'

Try the demo.

In the above examples, the behavior of both approaches is the same.

2. What’s the difference

The difference is seen when the success() callback of the resolved promise returns a rejected promise. That might happen when the resolved value is invalid.

Let’s modify the success callback to return a rejected promise:

function rejectSuccess(invalidValue) {
  console.log('Invalid success: ', invalidValue);
  return Promise.reject('Invalid!');}

Now let’s use rejectSuccess in both approaches:

Promise.resolve('Zzz!')
 .then(rejectSuccess, error);
// Logs 'Invalid success: Zzzzz!'

Promise.resolve('Zzz!')
 .then(rejectSuccess)
 .catch(error);
// Logs 'Invalid success: Zzzzz!'
// Logs 'Error: Invalid!'

Try the demo.

Promise.resolve('Zzz!').then(rejectSuccess, error) only calls rejectSuccess, even if rejectSuccess returns a rejected promise. error callback is not invoked.

Promise.resolve('Zzz!').then(rejectSuccess).catch(error) calls rejectSuccess because the promise is resolved. But rejectSuccess returns a rejected promise, — it is caugth by .catch(error) and the error callback is invoked. That’s the difference.

3. When to use

That could be useful, for example, when you perform a fetch request to get a list of items, but the list must obligatory have at least one item.

So, in case if the list is empty, you could simply reject that list:

import axios from "axios";

axios("/list.json")  .then(response => {    const list = response.data;    if (list.length === 0) {
      return Promise.reject(new Error("Empty list!"));
    }
    return list;
  })
  .catch((err) => {
    console.log(err);
  });

Try the demo.

In the above example .catch(error) would catch the request errors and the empty list error.

4. Conclusion

The main difference between the forms promise.then(success, error) and promise.then(success).catch(error) is that in case if success callback returns a rejected promise, then only the second form is going to catch that rejection.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK