为什么要处理异常?
1.不处理直接导致程序奔溃,这显然不是我们想要的
2.导致请求无法被释放,直至连接超时。用户体验体验非常差,我们要做的应该是在出错时,给用户一个友好的提示,并记录下此次异常,以便排查。
Node.js中常用的异常处理方式
// 每秒钟打印一次时间,确保程序没有奔溃
(function loop() {
console.log(new Date().getTime())
setTimeout(function () {
loop()
}, 1000)
})()
// 模拟同步代码块内出现异常
let syncError = () => {
throw new Error('Sync Error')
}
// 模拟异步代码块内出现异常
let asyncError = () => {
setTimeout(function () {
throw new Error('Async Error')
}, 100)
}
1、try catch 方式
try {
syncError()
} catch (e) {
/*处理异常*/
console.log(e.message)
}
console.log('异常被捕获了,我可以继续执行')
但是try catch方式无法处理异步代码块内出现的异常,你可以理解为执行catch时,异常还没有发生。
try {
asyncError()
} catch (e) {
/*异常无法被捕获,导致进程退出*/
console.log(e.message)
}
2、callback方式
fs.mkdir('/dir', function (e) {
if (e) {
/*处理异常*/
console.log(e.message)
} else {
console.log('创建目录成功')
}
})
3、event 方式
let events = require("events");
//创建一个事件监听对象
let emitter = new events.EventEmitter();
//监听error事件
emitter.addListener("error", function (e) {
/*处理异常*/
console.log(e.message)
});
//触发error事件
emitter.emit("error", new Error('出错啦'));
4、Promise 方式
new Promise((resolve, reject) => {
syncError()
/* or
try{
syncError()
}catch(e){
reject(e)
}
*/
})
.then(() => {
//...
})
.catch((e) => {
/*处理异常*/
console.log(e.message)
})
Promise同样无法处理异步代码块中抛出的异常
new Promise((resolve, reject) => {
asyncError()
})
.then(() => {
//...
})
.catch((e) => {
/*异常无法被捕获,导致进程退出*/
console.log(e.message)
})
5、Async/Await 方式
Async/Await是基于Promise的,所以Promise无法捕获的异常,Async/Await同样无法捕获
var sleep = function (time) {
return new Promise(function (resolve, reject) {
syncError()
})
};
(async function () {
try {
await sleep(100);
} catch (e) {
/*处理异常*/
console.log(e.message)
}
})()
6、process方式
process方式可以捕获任何异常(不管是同步代码块中的异常还是异步代码块中的异常)
process.on('uncaughtException', function (e) {
/*处理异常*/
console.log(e.message)
});
asyncError()
syncError()
7、domain方式
process方式虽然可以捕获任何类型的异常,但是process太过笨重,除了记录下错误信息,其他地方不适合使用,domain这个也可以处理任何类型异常的模块,显然是一个不错的选择。
let domain = require('domain')
let d = domain.create()
d.on('error', function (e) {
/*处理异常*/
console.log(e.message)
})
d.run(asyncError)
d.run(syncError)