随着您的项目的发展,我们开始在任何地方都拥有这个非常受欢迎的防御性代码片段:
func(err, result){
if(err){
console.log('An error occurred!, @myModule :' + err);
return callback(err);
}
//then the rest..
}
快速谷歌搜索显示一些试图克服这一共同关注点的库,例如https://www.npmjs.com/package/callback-wrappers
但是,在不影响我们的早期错误处理机制的情况下,最小化样板编码的最佳方法是什么?
答案 0 :(得分:2)
有两种方法可以帮助您缓解这个问题,两种方法都使用外部模块。
首先,我首选的方法是使用async,特别是async.series,async.parallel或async.waterfall。如果在任何异步调用中发生错误,这些方法中的每一个都将直接跳到最后一个函数,从而防止在整个回调过程中出现if(err)
条件。
例如:
async.waterfall([
function(cb) {
someAsyncOperation(cb);
},
function(result, cb) {
doSomethingAsyncWithResult(result, cb);
}
], function(err, result) {
if(err) {
// Handle error - could have come from any of the above function blocks
} else {
// Do something with overall result
}
});
另一种选择是使用promise库,例如q。它有一个函数Q.denodeify
来帮助你将回调式代码包装成promise样式。使用承诺,您可以使用.then.
,.catch
和.done
:
var qSomeAsyncOperation = Q.denodeify(someAsyncOperation);
var qDoSomethingAsyncWithResult = Q.denodeify(doSomethingAsyncWithResult);
Q()
.then(qSomeAsyncOperation)
.then(qDoSomethingAsyncWithResult)
.done(function(result) {
// Do something with overall result
}, function(err) {
// Handle error - could have come from any of the above function blocks
});
我更喜欢使用async
,因为它更容易理解发生了什么,并且它更接近于node.js采用的真实回调风格。