在 nodejs 中,当您使用错误优先模式调用异步函数时,即使您无法在当前函数级别处理错误而只想将其传输到上层,您也必须这样写:
var myAsyncFunc = function (callback) {
doStuff();
doAsyncStuff(function (err, res) {
if (err) {
callback(err);
return;
}
res = doSomeOtherStuff(res);
callback(null, res);
});
};
4 行“if (err) ...”表示“我无法处理这里的错误,所以我只是传播它”。
对我来说,这看起来真的不是处理错误的优雅方式。就像在同步代码中我必须这样做:
void mySyncFunc() {
doStuff();
try {
int res = doSyncStuff();
return doSomeOtherSuff(res);
} catch (SomeException e) {
throw e;
}
}
这将是可怕的,我很高兴能够写:
void mySuncFunc() throws SomeException {
doStuff();
int res = doSyncStuff();
return doSomeOtherStuff(res);
}
在有人说之前, async.series 并没有改变这个问题(它只允许更少的嵌套,但你仍然需要执行 if(err) 部分)。
Promise 允许编写更紧凑和优雅的代码。但是它们仍然为语言添加了一个很大的层,并且大多数 nodejs 模块不使用这些。
我的问题是:
最佳答案
响应式(Reactive)扩展
我能想到的另一种选择,你还没有提到:Reactive Extensions .但就像 promises 一样,它为回调添加了一层抽象,让您可以在操作符链的末尾处理错误:
var observedAsyncFunc = Rx.Observable.fromCallback(asyncFunc);
这将返回一个函数,您可以运行该函数并可选择将参数放入其中(这是 asyncFunc 所期望的)
var source = observedAsyncFunc(); //this "runs" the asyncFunc (/returns the observable)
现在开始“操作”(在本例中,结果只是与自身相乘):
source
.map(result => result * result)
//...
...最后,当您完成操作后,订阅 observable,您可以在其中对结果采取行动并处理错误:
source
.map(result => result * result)
.subscribe(
result => console.log("we got something "+result),
error => console.log("ERROR"),
() => console.log("observable completed")
);
promise
我知道你写了,你不想听到任何关于任何 promise 的废话,但你也写了你有很多 Node 模块没有实现 promise 的问题。这实际上不是问题,因为(鉴于 Node 模块中的异步函数符合标准回调模式)您可以
promisify()
使其返回 promise 的功能。如果您使用 Bluebird例如,您可以:var Promise = require('bluebird');
var promisifiedAsyncFunc = Promise.promisify(asyncFunc);
promisifiedAsyncFunc()
.then(function(res){/*...*/})
.catch(function(err){/*...*/});
关于node.js - nodejs 中错误优先模式和 promise 的替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38119684/