将try/catch
与Promise
打包在一起是不错的做法?我正在审核下面的代码,我似乎无法理解在try/catch
中有Promise
块的必要性。另外,为什么没有Promise
拒绝的地方,正如您在catch
块中看到的那样Promise
结算。请帮助我理解这段代码,在最佳实践和效率方面,try/catch
内部Promise
。{/ p>
我也非常感谢有关清除代码冗余的任何建议。
getRoute(): any {
return async (request: any, reply: any) => {
const result = new Promise<string>( async (resolve, reject) => {
try {
let userIsValid = await this.validator.validate(request.payload, RegisterUserValidator);
if (userIsValid.error) {
resolve(responseHelper.getErrorResponse(ResponseErrorCode.joiValidatorError, userIsValid.error));
throw new ControlFlowNonError();
}
let results = await this.authUser.registerUser(request.payload);
resolve(responseHelper.getSuccessResponse(results, null));
}
catch (error) {
let message: ILogMessage = {
code: ResponseErrorCode.unknownError,
message: ResponseErrorCode.unknownError.toString(),
meta: error,
sourceFunction : 'ApiDataCreateCredentials: getRoute()'
};
this.logHelper.error(message);
resolve(error);
}
});
reply(result);
};
};
答案 0 :(得分:2)
最好在promise [executor function]中包含try / catch块吗?
不,这不是最佳做法。几乎没有理由在promise执行器函数中使用promises。因为当你这样做时,你根本不需要外部的手工创造的承诺。你可以回归内心的承诺。这是Promise constructor anti-pattern。
仅供参考,虽然这不是你的情况,但是使用try/catch
来处理promise执行者中的常规异常是合理的(如果首先实际需要手动创建的promise执行者,并且如果常规异常是值得关注的,您希望在本地处理它们。)
这是另一个如何实现相同逻辑的想法。这将删除围绕承诺的promise anti-pattern与另一个手动创建的承诺,并使用承诺流控制使userIsValid.error
转到日志错误代码。我没有看到在这里使用等待的任何特殊优势,所以我切换回使用.then()
和.catch()
。我不知道TypeScript,所以这是代码的常规Javascript版本,但您可以自己添加轻微的语法差异,将其转回TypeScript:
getRoute(): function() {
return function(request, reply) {
return this.validator.validate(request.payload, RegisterUserValidator).then(userIsValid => {
if (userIsValid.error) {
// treat this as an error condition
throw responseHelper.getErrorResponse(ResponseErrorCode.joiValidatorError, userIsValid.error);
}
return this.authUser.registerUser(request.payload).then(results => responseHelper.getSuccessResponse(results, null));
}).catch(error => {
let message: ILogMessage = {
code: ResponseErrorCode.unknownError,
message: ResponseErrorCode.unknownError.toString(),
meta: error,
sourceFunction : 'ApiDataCreateCredentials: getRoute()'
};
this.logHelper.error(message);
// turn back into resolved promise with error as the result
return error;
}).then(reply); // always call reply
}
}
您的实施似乎并不理想的事情:
resolve()
(第二个将被忽略,但以这种方式编码似乎不太理想)async/await
似乎没有任何特别的好处。这似乎使流程复杂化(在我看来)。resolve()
后跟throw
是一个真正的头脑。是的,人们最终可以弄清楚你正在尝试做什么,但这是一个奇怪的方法。我的方案更具语义性。 if (userIsValid.error)
对你来说真的只是一个错误条件,所以这样编码只会让它变得更加明显。然后,由于您希望所有错误继续进行,就好像没有错误(在记录之后),我们只是使.catch()
处理程序正常返回,这允许始终调用最后一个.then()
处理程序。与您的主题相关的其他参考:
Can't throw error from within an async promise executor function
Is it an anti-pattern to use async/await inside of a new Promise() constructor?