关于Promise那些事系列(5)

85 阅读2分钟

「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」。

Promisecatch方法来了。

image.png

Promise.prototype.catch()

1. 基本介绍

Promise.prototype.catch()方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

HttpX('/posts.json').then(function(posts) {
  // ...
}).catch(function(error) {
  // 处理 HttpX 和 前一个回调函数运行时发生的错误
  console.log('发生错误!', error);
});

上面这段代码中,HttpX方法返回一个 Promise 对象,如果该对象状态从pending变为resolved,就会调用then()方法指定的回调函数;如果异步操作抛出错误,那么状态就会从pending变为rejected,就会调用catch()方法指定的回调函数,处理这个错误。另外,then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获。

2. 案例

const promise = new Promise(function(resolve, reject) {
  throw new Error('错误');
});
promise.catch(function(error) {
  console.log(error);
});
// Error: 错误

上面这段代码中,promise对象抛出了一个错误,会被catch方法指定的回调函数捕获错误。 我们也可以采用trycatch的方法,看下面这两段代码

// 写法一
const promise = new Promise(function(resolve, reject) {
  try {
    throw new Error('错误');
  } catch(error) {
    reject(error);
  }
});
promise.catch(function(error) {
  console.log(error);
});
// 写法二
const promise = new Promise(function(resolve, reject) {
  reject(new Error('错误'));
});
promise.catch(function(error) {
  console.log(error);
});

这里也可以看出来,reject方法的作用,和catch抛出错误效果是一样的。

3. catch

上面说的catch也可以抛出错误,但是Promise状态已经变成resolved,这个时候在抛出的错误是无效的。

const promise = new Promise(function(resolve, reject) {
  resolve('ok');
  throw new Error('test');
});
promise
  .then(function(value) { console.log(value) })
  .catch(function(error) { console.log(error) });
// ok

上面代码中,Promise 在resolve语句后面,再抛出错误,不会被捕获,等于没有抛出。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。

try/catchreject

跟的try/catch方法不同的是,如果没有使用catch()方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应。

const someAsyncThing = function() {
  return new Promise(function(resolve, reject) {
    // 下面一行会报错,因为x没有声明
    resolve(x + 2);
  });
};

someAsyncThing().then(function() {
  console.log('everything is great');
});

setTimeout(() => { console.log(123) }, 2000);
// Uncaught (in promise) ReferenceError: x is not defined
// 123