Promise捕获异常

156 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情 Promise是es6的新语法,是解决异步问题的一种解决方案。

promise有三种状态:

  • 待定状态(pending): 初始状态,不是成功状态也不是失败状态。
  • 成功状态(fulfilled): 意味着操作成功完成。
  • 失败状态(rejected): 意味着操作失败。

当promise是失败状态时,我们必须将其捕获处理,否则控制台则会报错提醒!

function a() {
  return new Promise((resolve, reject) => {
    setTimeout(reject(new Error()), 2000)
  })
}

如上,我们有一个函数a,执行两秒后会返回一个失败的Promise的,值是一个错误对象。当我们直接执行a函数,不做任何处理时,控制台报错如下:


接下来我们介绍一下如何处理失败的Promise。

.then捕获失败的promise

then接受两个参数,分别是成功的Promise的回调,和失败的Promise的回调,当我们有处理失败的Promise的回调,控制台则不会报错,也就不会导致我们代码执行中断。

function run() {
    a()
        .then(
            (res) => { console.log(res) },
            (err) => { console.log(err, 'play error') }
        )
}
.catch捕获失败的promise

如果我们没有在then方法中写错误的回调,则失败的Promise会进入到catch方法中

function playB() {
    a()
        .then(res => console.log(res))
        .catch(error => console.log(error,'playB error'))
}
try/catch捕获失败的promise

使用try/catch捕获时,一般我们promise也不会采取以上两种链式调用的方法,而是采用async await语法糖来达到同步执行的效果。这样当返回的是失败的Promise时,会进入到catch的代码块,不会报错卡死js

async function b() {
    try {
        let aa = await a()
    } catch (error) {
        console.log(error)
    }
}

除了以上几种比较常见的捕获失败Promise的方法外,还有另外一种全局捕获pormise的错误的方法

window.addEventListener('unhandledrejection', event => {
    let { reason, promise } = event
    event.preventDefault()
})

需要注意的是,全局捕获需要组织冒泡,否则控制台还是会报错。

我们可以通过reason的信息查找到对应的失败Promise的位置, reason显示报错位置是17行,对应的正好是我们返回失败的Promise的位置!