代码的作品,但最好的做法是有一个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 } } 

事情似乎并不理想与您的实施:

  1. 承诺反模式 (创造一个不必要的包装承诺)。
  2. 多次调用resolve() (第二个会被忽略,但是用这种方式编写代码似乎并不理想)
  3. 在这里使用async/await似乎没有任何特别的好处。 这似乎使stream程复杂化(在我看来)。
  4. 当读取代码时, resolve()后面的throw是一个真正的头部划痕。 是的,你最终可以弄清楚你正在做什么,但这是一个奇怪的方式来做到这一点。 我的scheme有点语义。 if (userIsValid.error)对你来说真的只是一个错误条件,那么这样编码就更明显了。 然后,因为你想所有的错误继续进行,就好像没有错误(在日志之后),我们只是让.catch()处理程序正常返回,这允许最后的.catch()处理程序总是被调用。

其他参考资料与您的主题相关:

不能从asynchronous承诺执行器函数中抛出错误

在新的Promise()构造函数中使用asynchronous/等待的反模式?