处理 Node.Js 中的异常
Node.js 有 3 种处理异常/错误的基本方法:
try-catch
error
作为callback
的第一个参数emit
使用 eventEmitter 的错误事件
try-catch 用于捕获从同步代码执行中抛出的异常。如果调用者(或调用者的调用者,…)使用 try / catch,那么他们可以捕获错误。如果没有任何调用者尝试捕获而不是程序崩溃。
如果在异步操作上使用 try-catch,则异步方法的回调抛出异常,而不会被 try-catch 捕获。要从异步操作回调中捕获异常,最好使用 promises 。
更好地理解它的例子
// ** Example - 1 **
function doSomeSynchronousOperation(req, res) {
if(req.body.username === ''){
throw new Error('User Name cannot be empty');
}
return true;
}
// calling the method above
try {
// synchronous code
doSomeSynchronousOperation(req, res)
catch(e) {
//exception handled here
console.log(e.message);
}
// ** Example - 2 **
function doSomeAsynchronousOperation(req, res, cb) {
// imitating async operation
return setTimeout(function(){
cb(null, []);
},1000);
}
try {
// asynchronous code
doSomeAsynchronousOperation(req, res, function(err, rs){
throw new Error("async operation exception");
})
} catch(e) {
// Exception will not get handled here
console.log(e.message);
}
// The exception is unhandled and hence will cause application to break
回调主要在 Node.js 中使用,因为回调是异步传递事件的。用户向你传递一个函数(回调),并在异步操作完成后稍后调用它。
通常的模式是回调被调用为回调(错误,结果) ,其中只有一个错误和结果是非空的,这取决于操作是成功还是失败。
function doSomeAsynchronousOperation(req, res, callback) {
setTimeout(function(){
return callback(new Error('User Name cannot be empty'));
}, 1000);
return true;
}
doSomeAsynchronousOperation(req, res, function(err, result) {
if (err) {
//exception handled here
console.log(err.message);
}
//do some stuff with valid data
});
发出更复杂的情况,而不是使用回调,函数本身可以返回一个 EventEmitter 对象,并且调用者应该监听发射器上的错误事件。
const EventEmitter = require('events');
function doSomeAsynchronousOperation(req, res) {
let myEvent = new EventEmitter();
// runs asynchronously
setTimeout(function(){
myEvent.emit('error', new Error('User Name cannot be empty'));
}, 1000);
return myEvent;
}
// Invoke the function
let event = doSomeAsynchronousOperation(req, res);
event.on('error', function(err) {
console.log(err);
});
event.on('done', function(result) {
console.log(result); // true
});