0%

JavaScript 的错误捕获

JavaScript 的错误捕获

异常类型

  1. EvalError,调用eval()时发生的异常,已被废弃只用于向后兼容而已
  2. InternalError,JavaScript引擎内部异常,FireFox独门提供的!
  3. RangeError,当函数实参越界时发生,如Array,Number.toExponential,Number.toFixed和Number.toPrecision时入参非法时。
  4. ReferenceError,当引用未声明的变量时发生
  5. SyntaxError,解析时发生语法错误
  6. TypeError,当值不是所期待的类型时,null.f()也报这个错
  7. URIError,当传递一个非法的URI给全局URI处理函数时发生,如decodeURIComponent(‘%’),即decodeURIComponent,decodeURI,encodeURIComponent,encodeURI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function promise1(i) {
return new Promise((resolve, reject) => {
console.log(i);
resolve('resolve promise1');
})
};

function promise2() {
return new Promise((resolve, reject) => {
console(2); // 这里是错误
})
};

function promise3() {
return new Promise((resolve, reject) => {
console.log(3);
resolve('resolve promise3');
})
};

try - catch

异步执行

在执行一系列的 Promise 时,如果是异步执行,(既不使用async await)则其他没有报错的 promise 会正常执行,而出错的 Promise 会在第一次执行的时候就被捕获
如果如下方法执行的话

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const main = async () => {
for (let i = 0; i < 5; i++) {
try {
promise1(i);
promise2();
promise3();
} catch(err) {
console.log(`err =>${err}`);
}
}
}

main();

// 返回

0
3
1
3
2
3
3
3
4
3
(node:3226) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: console is not a function

同步执行

如果使用了async await, main 函数变成这样

1
2
3
4
5
6
7
8
9
10
11
const main = async () => {
for (let i = 0; i < 5; i++) {
try {
await promise1(i);
await promise2();
await promise3(i);
} catch(err) {
console.log(`err =>${err}`);
}
}
}
1
2
3
4
5
6
7
8
9
10
0
err =>TypeError: console is not a function
1
err =>TypeError: console is not a function
2
err =>TypeError: console is not a function
3
err =>TypeError: console is not a function
4
err =>TypeError: console is not a function

那么代码在运行到 promise2();时就停下来,因为 promise3需要等待 promise2的结果,而 promise2又报错了,所以这个循环就会到此结束,promise3并不会执行.
如果想在同步执行,但是又不想因为promise2的错误影响promise3的执行,这个时候就需要在可能会出错的 promise 后使用.catch()

promise.catch()

1
2
3
4
5
6
7
8
9
10
11
12
13
const main = async () => {
for (let i = 0; i < 5; i++) {
try {
await promise1(i);
await promise2().catch(err => {
console.log(err)
});
await promise3();
} catch(err) {
console.log(`err =>${err}`);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
0
TypeError: console is not a function
at Promise (/Users/bhb/code/testTryCatch.js:10:9)
at new Promise (<anonymous>)
at promise2 (/Users/bhb/code/testTryCatch.js:9:12)
at main (/Users/bhb/code/testTryCatch.js:30:19)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
at Function.Module.runMain (module.js:678:11)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3
3
1
TypeError: console is not a function
at Promise (/Users/bhb/code/testTryCatch.js:10:9)
at new Promise (<anonymous>)
at promise2 (/Users/bhb/code/testTryCatch.js:9:12)
at main (/Users/bhb/code/testTryCatch.js:30:19)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
at Function.Module.runMain (module.js:678:11)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3
3
2
TypeError: console is not a function

如果在一系列的同步执行 promise 中,报错的 promise 后.catch().做了错误捕获和处理,那么就不会影响后面的 promise 执行.

promise.catch(throw err)

如果是

1
2
3
promise.catch((err) => {
throw(err)
})

那么当前这个 promise 的错误就被会抛出,被当前的 try - catch 所捕获,同样的,当前这个循环就被会终止

总结

  • 当 promise 被同步执行的时候,如果遇到错误,并且没有被.catch后进行错误处理,那么当前的方法就会到此结束,后面的代码都不会被执行.

  • 如果想一个 promise 的错误不影响整个方法的话,有2种方法:

    1. 如果后面的代码不是需要前面的 promise 执行的结果的话,则不使用 async await,
    2. 如果需要同步执行,则对可预期的容易报错方法进行单独的.catch() 并在方法里进行错误处理.
  • 当然,如果要求一定需要执行错误 promise 后的代码,则不需要单独处理,只需要在整个方法里上加上 try - catch 进行错误捕获,然后 throw 错误或者直接处理错误(一般就是 logger.error()).