我有一些通过快速路径获取数据的代码,如果快速路径不可用,我想实现回退到慢速路径。这里仍然是node.js的新手,所以我不知道该怎么做。
这是我的意思的一个简单例子:
function getThing(callback) {
var thang = getThingTheFastWay();
if (!thang) {
thang = getThingTheSlowWay();
}
if (!thang || !thang.validate()) {
return callback(new Error('invalid thang'));
}
callback(null, thang);
}
所以我的目标是异步执行getThingTheSlowWay()
中的I / O.此方法的后半部分是否需要提供给getThingTheSlowWay()
的回调?
答案 0 :(得分:1)
此方法的后半部分是否需要提供给
getThingTheSlowWay()
的回调?
是的,确切地说。您无法为异步结果执行thang =
。你的功能基本上是这样的:
function getThing(callback) {
var thang = getThingTheFastWay();
if (thang) {
if (!thang.validate())
callback(new Error('invalid thang'));
else
callback(null, thang);
} else {
getThingTheSlowWay(function(err, thang) {
if (!err && !thang.validate())
callback(new Error('invalid thang'));
else
callback(err, thang);
});
}
}
为避免重复,您需要使用命名函数:
function getThing(callback) {
function validateThang(err, thang) {
if (!err && !thang.validate())
callback(new Error('invalid thang'));
else
callback(err, thang);
}
var thang = getThingTheFastWay();
if (thang)
validateThang(null, thang);
else
getThingTheSlowWay(validateThang);
}
另一种方法是使用承诺。假设getThingTheSlowWay
返回一个承诺而getThingTheFastWay
没有承诺,它看起来像
function getThing() {
return Promise.resolve(getThingTheFastWay() || getThingTheSlowWay())
.then(function validateThang(thang) {
if (thang.validate())
return thang;
else
throw new Error('invalid thang');
});
}
答案 1 :(得分:1)
我建议你总是使用回调,无论是否有什么东西快速"或不。仅仅因为你认为速度快,并不意味着它总会如此 - 而且在高性能服务器的领域,为什么要写一些可以阻止它的东西同样容易?
function getThing(callback) {
var thang = getThingTheFastWay(function(err, thang) {
if (thang && !err) {
callback(err, thang);
} else {
getThingTheSlowWay(function(err, thang) {
callback(err, thang);
});
}
});
}
这当然需要对你的下游函数进行一些重写来支持回调,但值得做。即使您正在使用第三方功能来执行此操作,也可以将自己的回调包装在长时间运行的函数中。
答案 2 :(得分:0)
考虑使用承诺。 https://www.promisejs.org/承诺允许您执行某些操作,并在完成后执行回调。如果快速操作失败,则可以使用慢速操作进行恢复。所有这些行动都可以与承诺一起使用。
要考虑的一件事是,慢速操作可能不会慢,因为快速操作通常会阻塞。遇到大量请求时可能会出现问题。
如果您不想使用promises,请检查快速版本是否有效并立即执行回调并返回。如果它还没有返回,你可能需要将回调传递给get slow way函数,因为那将有一个异步调用,它将有一个回调来调用回调参数
答案 3 :(得分:0)
Promise在这里可能有用:
function getThing() {
return new Promise(function(resolve, reject) {
getThingTheFastWay().then(function(result) {
resolve(result);
}).catch(function() {
getThingTheSlowWay().then(function(result) {
resolve(result);
}).catch(function() {
reject();
});
});
});
}
使用它将是:
getThing().then(function(result) {
// do something with the result
});
您可以使用和声标志启用承诺,或使用bluebird等库(推荐)