本文主要总结javascript异步error的抛出和捕获。

首先我们有一个耗时的操作wait:

1
2
3
const wait = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms))
}

有一个函数foo调用了上面的wait

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const foo = async () => {
console.log(1)
await wait(2000)
console.log(2)
}

console.log(3)
await foo()
console.log(4)

// 3
// 1
// 等待约2秒
// 2
// 4

async函数foo发生异常的话,可以通过throw一个Error来抛出:

1
2
3
4
const foo = async () => {
await wait(2000)
throw new Error('Woops!')
}

error2

或者返回一个Promise.reject,不过throw error的方式更常用。

1
2
3
4
const foo = async () => {
await wait(2000)
return Promise.reject(new Error('Whoops!'))
}

foo发生异常后,可以通过catch来捕获,这样就不会报Uncaught错误。

1
2
3
4
5
const bar = async () => {
await foo().catch((e) => {
console.log(e) // caught
})
}

因为foo是一个async函数,返回的是一个Promise,所以可以像Promise捕获异常一样,直接在函数foo后面跟catch

或者用try-catch来捕获:

1
2
3
4
5
6
7
const bar = async () => {
try {
await foo() // caught
} catch(e) {
console.log(e)
}
}

对于异步函数,比如上面的foo,尽量在执行的时候用await,可以避免很多问题。比如用try-catch捕获异常时,如果没有await,就捕获不到:

1
2
3
4
5
6
7
const bar = async () => {
try {
foo() // uncaught
} catch(e) {
console.log(e)
}
}

上面这些操作基本就能捕获到异常,然后做一些异常处理逻辑,比如提示操作失败,隐藏处理中的提示等等。
编码时注意对异步逻辑的处理,最后就都能通过上面的方式捕获异常,更复杂的问题,可以试试Promise.all