最近,我读了TJ的博客文章:《告别Node.js》。
我不太明白Node失败的部分。
在我看来,Go中的错误处理更优越。Node的优点在于,您必须考虑每个错误,并决定要做什么。但是Node失败了,因为:
- 你可能会得到重复的回调
- 你可能根本得不到回调(在limbo中丢失)
- 你可能会得到带外错误
- 排放者可能会得到多个"错误"事件
- 缺少" error "事件将所有内容发送到地狱
- 经常不确定什么需要"错误"处理程序
- " error "处理程序非常冗长
- 回调吸
当作者写"你可能根本得不到回调(lost in limbo)"时,所指的具体问题是什么?
这意味着错误在limbo中丢失,因为操作函数没有"获得回调",即错误被"吞下",因为没有回调来处理它。
var foo = function(onSuccess, onFailure) {
// ...
// uh-oh, I failed
if(onFailure) {
onFailure(err);
}
else {
// well, that probably wasn't too important anyway...
}
}
foo(function() { console.log("success!"); } /* no second argument... */);
注意,在同步编码中(比如,大多数Java),这种情况很难发生。Catch块的执行要好得多,如果一个异常无论如何都逃掉了,它会转到未捕获的异常处理程序,默认情况下,该异常处理程序会导致系统崩溃。在node中也是这样,除了在上面的范例中没有抛出异常,它很可能被吞下。
在我上面的例子中,强社区约定可以解决这个问题,但是约定通常不能完全解决这个问题。参见支持done
方法的Q promise库。
Q.fcall(promisedStep1)
.then(promisedStep2)
.then(promisedStep3)
.then(promisedStep4)
.then(function (value4) {
// Do something with value4
})
.catch(function (error) {
// Handle any error from all above steps
})
.done();
done
调用指示promise链抛出任何未处理的异常(如果catch块丢失,或者catch块本身抛出)。但是调用done
完全是程序员的责任,因为只有程序员知道链何时完成。如果程序员忘记调用done
,则错误将在承诺链中悬挂。我曾经遇到过这样的bug;我同意,这是一个严重的问题。
我要诚实地说,帖子中的很多块对我来说没有多大意义。但我是一个经验丰富的Node.js程序员,这是我唯一能想到的可能意味着。