如何重构使用相同函数但在调用函数中还包含变量的 promise catch?
How to refactor a promise catch that uses the same function, but also a variable in the calling one?
我使用 ExpressJS for routing, and bluebird 作为 Promise。
我对几条路线重复了以下代码,最后它们都具有相同的 .catch 函数,并以 json 失败响应。
router.get('/', function(req, res) {
return somePromise
.then(function doesSomething(someVariable) {
doSomething;
})
.catch(function catchesError(err) {
return res.json({ success: false });
});
});
我想提取 catchesError 函数,但是它无法使用 res 对象。
有什么建议吗?
只需创建一个函数并将 res
对象作为参数传递,将 return 作为函数传递。
function makeErrorCatcher(res) {
return function catchesError(err) {
return res.json({
success: false
});
}
}
router.get('/', function (req, res) {
return somePromise
.then(function doesSomething(someVariable) {
doSomething;
})
.catch(makeErrorCatcher(res));
});
您可以修饰 .get
以传递一个默认的捕获处理程序。 (假设您对自定义路由器不感兴趣):
Object.keys(router).forEach(function(key){ // for each method
router[key+"P"] = function(path, fn){ // create a decorated alt
router[key].call(router, function(req, res, next){ // delegate
var that = this, args = arguments;
return Promise.try(function(){ // wrap to make throw safe
return fn.apply(that, args); // delegation
}).catch(function catchesError(err){
// LOG YOUR ERRORS, DON'T CATCH ALL
return res.json({ success: false });
});
});
};
});
这会让你做:
router.getP('/', function(req, res) {
return somePromise.then(function doesSomething(someVariable) {
doSomething;
});
});
现在将自动捕获错误并发送适当的 JSON。消除重复或完全忘记错误的可能性。
与 Ben Fortune 的解决方案非常相似,使用 bind()
:
function catchesError(res, err) {
return res.json({ success: false });
}
router.get('/', function(req, res) {
return somePromise
.then(function doesSomething(someVariable) {
doSomething;
})
.catch(catchesError.bind(null, res));
});
如果您在 class.
中,请将 null 替换为 this
如果您不打算使用承诺链,您可以添加一个附加 catch
处理程序的 catcher
函数:
function catcher(promise, req, res) {
promise.catch(function catchesError(err) {
return res.json({ success: false });
});
return promise;
}
router.get('/', function(req, res) {
return catcher(somePromise, req, res)
.then(function doesSomething(someVariable) {
doSomething;
});
});
但是,如果您想使用出色的承诺链机制,则需要手动调用 catch
处理程序以确保它是链中的最后一个:
function makeCatchHandler(res) {
return function(err) {
return res.json({ success: false });
};
}
router.get('/', function(req, res) {
return catcher(somePromise, req, res)
.then(function doesSomething(someVariable) {
doSomething;
}).catch(makeCatchHandler(res));
});
我使用 ExpressJS for routing, and bluebird 作为 Promise。 我对几条路线重复了以下代码,最后它们都具有相同的 .catch 函数,并以 json 失败响应。
router.get('/', function(req, res) {
return somePromise
.then(function doesSomething(someVariable) {
doSomething;
})
.catch(function catchesError(err) {
return res.json({ success: false });
});
});
我想提取 catchesError 函数,但是它无法使用 res 对象。
有什么建议吗?
只需创建一个函数并将 res
对象作为参数传递,将 return 作为函数传递。
function makeErrorCatcher(res) {
return function catchesError(err) {
return res.json({
success: false
});
}
}
router.get('/', function (req, res) {
return somePromise
.then(function doesSomething(someVariable) {
doSomething;
})
.catch(makeErrorCatcher(res));
});
您可以修饰 .get
以传递一个默认的捕获处理程序。 (假设您对自定义路由器不感兴趣):
Object.keys(router).forEach(function(key){ // for each method
router[key+"P"] = function(path, fn){ // create a decorated alt
router[key].call(router, function(req, res, next){ // delegate
var that = this, args = arguments;
return Promise.try(function(){ // wrap to make throw safe
return fn.apply(that, args); // delegation
}).catch(function catchesError(err){
// LOG YOUR ERRORS, DON'T CATCH ALL
return res.json({ success: false });
});
});
};
});
这会让你做:
router.getP('/', function(req, res) {
return somePromise.then(function doesSomething(someVariable) {
doSomething;
});
});
现在将自动捕获错误并发送适当的 JSON。消除重复或完全忘记错误的可能性。
与 Ben Fortune 的解决方案非常相似,使用 bind()
:
function catchesError(res, err) {
return res.json({ success: false });
}
router.get('/', function(req, res) {
return somePromise
.then(function doesSomething(someVariable) {
doSomething;
})
.catch(catchesError.bind(null, res));
});
如果您在 class.
中,请将 null 替换为this
如果您不打算使用承诺链,您可以添加一个附加 catch
处理程序的 catcher
函数:
function catcher(promise, req, res) {
promise.catch(function catchesError(err) {
return res.json({ success: false });
});
return promise;
}
router.get('/', function(req, res) {
return catcher(somePromise, req, res)
.then(function doesSomething(someVariable) {
doSomething;
});
});
但是,如果您想使用出色的承诺链机制,则需要手动调用 catch
处理程序以确保它是链中的最后一个:
function makeCatchHandler(res) {
return function(err) {
return res.json({ success: false });
};
}
router.get('/', function(req, res) {
return catcher(somePromise, req, res)
.then(function doesSomething(someVariable) {
doSomething;
}).catch(makeCatchHandler(res));
});