代码的作品,但最好的做法是有一个try / catch块内的承诺?
用Promise
包装try/catch
是不是很好? 我正在审查下面的代码,我似乎无法理解在Promise
中使用try/catch
块的必要性。 另外,为什么没有Promise
拒绝的地方,正如你可以在catch
块中看到Promise
解决的那样。 请帮我理解这段代码,就最佳实践和效率而言,在Promise
中有try/catch
的意思。
我也非常感谢任何有关清理代码的build议。
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); }; };
在promise [executor函数]中放置try / catch块是否是最佳做法?
不,这不是最好的做法。 承诺执行程序函数内部没有任何理由使用promise。 因为当你这样做的时候,你根本不需要外部的手工创build的承诺。 你可以回到内心的承诺。 这是Promise构造函数的反模式 。
仅供参考,虽然在这里不是你的情况,但使用try/catch
处理承诺执行程序中的常规exception是合理的(如果首先真正需要手动创build的承诺执行程序,并且如果常规exception是关心的,想要在本地处理)。
这是另一个如何完成相同逻辑的想法。 这消除了与另一个手动创build的诺言userIsValid.error
的承诺反模式 ,并使用承诺stream控制使userIsValid.error
转到日志错误代码。 我没有看到在这里使用await的任何特别的优势,所以我切换回使用.catch()
和.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
似乎没有任何特别的好处。 这似乎使stream程复杂化(在我看来)。 - 当读取代码时,
resolve()
后面的throw
是一个真正的头部划痕。 是的,你最终可以弄清楚你正在做什么,但这是一个奇怪的方式来做到这一点。 我的scheme有点语义。if (userIsValid.error)
对你来说真的只是一个错误条件,那么这样编码就更明显了。 然后,因为你想所有的错误继续进行,就好像没有错误(在日志之后),我们只是让.catch()
处理程序正常返回,这允许最后的.catch()
处理程序总是被调用。
其他参考资料与您的主题相关:
不能从asynchronous承诺执行器函数中抛出错误
在新的Promise()构造函数中使用asynchronous/等待的反模式?