请教,Nodejs中为什么这里throw触发了2个实例的?
请教,Nodejs中为什么这里throw触发了2个实例的?
function class1(name){
this.name = name;
var _this = this;
process.on(‘uncaughtException’, function (e) {
_this.err(e);
});
}
class1.prototype.func1 = function(){
console.log(this.name);
if(this.name==‘aaa’)
throw ‘error’;
};
class1.prototype.err = function(e){
console.log(this.name + e);
};
var c1 = new class1(‘aaa’);
var c2 = new class1(‘bbb’);
c1.func1();
c2.func1();
输出结果 aaa aaaerror bbberror
为什么c2实例也触发了?应该怎么写才会是只触发c1的?
在这个例子中,throw 'error';
语句抛出一个异常,而该异常被全局的 process.on('uncaughtException')
监听器捕获。这意味着无论哪个实例调用 func1()
方法并抛出异常时,全局的错误处理程序都会接收到该异常,并且会执行 _this.err(e);
这一行代码。
由于 process.on('uncaughtException')
是全局的,因此它会捕获所有未捕获的异常,包括 c1
和 c2
实例的异常。因此,当 c1
抛出异常时,c2
也会因为同一个错误处理程序而触发。
为了仅捕获特定实例的异常,你可以将错误处理程序移到每个实例内部。这样,每个实例的错误处理程序只会处理它自己的异常。
下面是修改后的代码示例:
function class1(name) {
this.name = name;
}
class1.prototype.func1 = function() {
try {
console.log(this.name);
if (this.name == 'aaa') {
throw 'error';
}
} catch (e) {
this.err(e);
}
};
class1.prototype.err = function(e) {
console.log(this.name + e);
};
var c1 = new class1('aaa');
var c2 = new class1('bbb');
c1.func1();
c2.func1();
在这个修改后的版本中,func1
方法内部包含了一个 try...catch
块,用于捕获并处理当前实例的异常。这样,只有 c1
的异常会被处理,而 c2
的 func1
方法不会触发错误处理程序。
输出结果将会是:
aaa
aaaerror
bbb
这样就实现了仅捕获特定实例的异常。
你在c1.func1()
和c2.func1()
中间,console.log(‘1111’),会发现1111根本没输出。
c2根本没触发,而是你给process的 uncaughtException 注册了2个监听函数,所以c1
throw后,执行了2个函数。两个函数不同,但是内容是一样的。因为闭包的原因,一个_this.name为aaa,一个_this.name为bbb,e为error,所以就有上面的输出了
哦,原来是这样,就是说throw后程序就断了。那如何catch一个不受控的throw,并保持程序不断呢?
你这个根本就不是throw了两次 而是你绑定了两次uncaughtException事件, 所以输出了两次
在你的代码中,process.on('uncaughtException', ...)
监听了整个进程的未捕获异常事件。这意味着无论哪个实例抛出异常,该监听器都会被触发。这就是为什么 c1.func1()
抛出异常时,c2
实例的错误处理函数也会被调用。
要使错误仅触发 c1
的错误处理函数,可以将错误监听器放在单个实例的上下文中。你可以通过修改类原型的方法来实现这一点:
function Class1(name) {
this.name = name;
}
Class1.prototype.func1 = function () {
console.log(this.name);
if (this.name == 'aaa') throw 'error';
};
Class1.prototype.err = function (e) {
console.log(this.name + e);
};
Class1.prototype.start = function () {
try {
this.func1();
} catch (e) {
this.err(e);
}
};
var c1 = new Class1('aaa');
var c2 = new Class1('bbb');
c1.start(); // 只会触发 c1 的错误处理函数
c2.start(); // 不会触发错误
在这个修改后的版本中,每个实例都有自己的错误处理逻辑,只有当实例自身抛出异常时,才会调用自己的错误处理函数。这样就不会出现两个实例共享同一个全局错误处理器的情况了。