try catch不能捕获promise的错误

参考链接
try catch不是万能的,不能捕获promise的错误。但可以promise接catch来捕获错误,如果有多层的promise,每层都要加catch。
代码示例

// 捕获失败
try {
    new Promise((resolve,reject)=>{
        throw Error(1)
    })
} catch (e) {
    console.error('catch error')
}

// 能捕获
try {
    new Promise((resolve,reject)=>{
        throw Error(1)
    }).catch(e=>{
        console.error('error catch!')
    })
} catch (e) {
    console.error('catch error', e)
}

// 多层 不能
try {
    new Promise((resolve,reject)=>{
        return new Promise(()=>{
            throw new Error(1)
        })
    }).catch(e=>{
        console.error('error catch!')
    }
    )
} catch (e) {
    console.error('catch error', e)
}

// 每层都catch,然后reject外抛,能捕获
try {
    new Promise((resolve,reject)=>{
        return new Promise(()=>{
            throw new Error(1)
        }).catch(e=>{
            return reject(e)
        })
    }).catch(e=>{
        console.error('error catch!')
    }
    )
} catch (e) {
    console.error('catch error', e)
}

这里的原理是啥?
参考这里,promise的executor里(就是这里)默认有个try catch,当有异常时就会执行reject并把异常作为参数。

我们知道try catch能捕获try代码块的异常,但如果异常在promise里抛出,那异常不是立即执行的,而是调用了reject,而reject是加到microtask里执行的,详细可以了解下javascript的event loop机制
比如如下代码

console.log(1)
new Promise((resolve) => {
  console.log(2)
  throw Error(4)
}).then((e) => { console.log(e) })
console.log(3)

会输出1、2、3后,再抛出异常4。到异常4的时候,已经不在try catch的marcotask了,try catch里的部份已经执行完了,而是在microtask里处理这个异常,所以捕获不了

console.log(1)
new Promise((resolve) => {
  console.log(2)
  throw Error(4)
}).catch(e=>{console.warn(e)})
console.log(3)

所以这样能捕获

这样也可以

new Promise(r=>{

    try{eee} catch(e){console.warn(e)}
})
// ReferenceError: eee is not defined

但这样不行,同理setTimeout异步执行的,try里面的代码实际已经跑完了

try {
    setTimeout(()=>{eee})
}catch(e) {

    console.warn(e)
}

还有一种方法也能捕获,加上await

async function getSomeValue() {
    throw new Error('uh oh');
}

async function a() {
  try {
    const someValue = await getSomeValue();
  } catch (error) {
    console.warn(error);
  }
}

await是等待promise resolve或reject后才继续执行之后的代码,那为啥在外面加try catch就能捕获到?是因为执行又回到macrotask了?

你可能感兴趣的:(javascript,promise)