如何重构一个使用相同函数的promise catch,但在调用函数中也是一个变量?
Posted
技术标签:
【中文标题】如何重构一个使用相同函数的promise catch,但在调用函数中也是一个变量?【英文标题】:How to refactor a promise catch that uses the same function, but also a variable in the calling one? 【发布时间】:2015-06-27 03:11:34 【问题描述】:我使用ExpressJS 进行路由,bluebird 用于 Promises。 我对几条路线重复了以下代码,最后它们都具有相同的 .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 对象。
有什么建议吗?
【问题讨论】:
【参考方案1】:只需创建一个函数并将res
对象作为参数传递并返回一个函数。
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));
);
【讨论】:
+1,尽管我推荐一个命名方案,如function makeErrorCatcher(res) return function catchesError(err) …
【参考方案2】:
您可以装饰.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。消除重复或完全忘记错误的可能性。
【讨论】:
【参考方案3】:很像 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));
);
如果您在上课,请将 null 替换为 this
。
【讨论】:
与 Ben Fortune 的解决方案相比,使用 .bind 的优缺点是什么? 先生。财富的解决方案基本上是绑定的。当您不确定bind()
是否可用时,这就是您使用的——用于浏览器的代码。在 Node.js 中,我们知道该功能将可用。无需自己动手。
bind()
还支持附加this
和开箱即用的可变数量的参数。它在许多其他情况下很有用:计时器回调和事件处理程序是最明显的。【参考方案4】:
如果您不打算使用承诺链,您可以添加一个附加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));
);
【讨论】:
以上是关于如何重构一个使用相同函数的promise catch,但在调用函数中也是一个变量?的主要内容,如果未能解决你的问题,请参考以下文章