【问题标题】:How to bubble error correctly from Promise without throw?如何从 Promise 中正确冒泡错误而不抛出?
【发布时间】:2014-11-05 05:31:36
【问题描述】:

我有以下 TypeScript 方法返回一个承诺:

public loadSavedLogin(): ng.IPromise<MyApp.Models.User> {
   return this._myAppService.getUser(this.savedUserId).then((result: MyApp.Models.User) => {
       if (result) {
          this.userId = result.UserID;
          this.userName = result.UserName;
        }
        return result;
     }, (error) => {
           this._isAuthError = true;
           return  error;
     }
  );
}

我遇到的问题在于 promise 的 error 回调。对该方法的上游调用也依赖于一个承诺,因此如果错误没有正确冒泡,上游承诺就不能正常工作。我找到了一个 hackish 解决方案:

(error) => {

      try {
             this._isAuthError = true;
             return error;
           } catch (e) {
              //If any error occurred above make sure to still throw
              throw error;
           } finally {
                //Allow upstream promises to continue as expected
                throw error;
           }
 }

这行得通,但看起来、感觉起来,而且可能全都错了。在处理和冒泡承诺中的错误时,我觉得我错过了正确的实现。正如我所做的那样,必须有一种更正确/正确的方法来处理 this 承诺中的错误函数,但仍然允许上游承诺在处理时对该方法的调用也能正常工作他们自己的错误函数。

如果没有一系列骇人听闻的throw 语句,如何让错误冒泡?

注意:返回错误并抛出似乎是多余的,但是如果我不返回值,我正在使用的IPromise 接口将无法编译。这就是我返回并抛出错误的原因。

注意:我阅读了大量关于使用 Promise 处理错误的问题,但没有一个回答我所问的关于防止我采取的骇人听闻的方法的问题。

【问题讨论】:

    标签: javascript angularjs typescript


    【解决方案1】:

    我不熟悉 TypeScript,但这里有一个 javascript 解决方案,您可以在其中使用 $q.reject

    .then(function() {}, 
          function(error) {
              this._isAuthError = true; 
              return $q.reject(error); 
          });`
    

    【讨论】:

    • ...或Promise.reject(error)ECMA6 Promises
    • 我也试过这个,但它在运行时不能正常工作。没有像我使用的示例那样达到预期的结果。在我的TypeScript 类的构造函数中,我有this._q = $q;。所以然后在error 函数中我尝试了:this._q.reject(error); 它构建得很好,但似乎没有正确地冒泡错误。还需要什么吗?
    • 对不起函数的最后一条语句应该是return $q.reject(error)
    • @atconway : 除非你重新定义$q,否则为什么需要将它存储在你的类中?
    • @spender - 是的,在我的TypeScript 类中,我有它实现ng.IQService 这样:private _q: ng.IQService; 所以它不是默认的$q 用于TS 功能的目的。
    【解决方案2】:

    只需抛出错误而不是永远返回它:

    public loadSavedLogin(): ng.IPromise<MyApp.Models.User> {
       return this._myAppService.getUser(this.savedUserId).then((result: MyApp.Models.User) => {
           if (result) {
              this.userId = result.UserID;
              this.userName = result.UserName;
            }
            return result;
         }, (error) => {
               this._isAuthError = true;
               throw  error;
         }
      );
    }
    

    请注意,来自拒绝处理程序的有效返回(即不返回承诺/被拒绝的承诺)会使链中的下一个承诺履行

    【讨论】:

    • 我实际上已经尝试过了,但是如果从我在 OP 中的注释中看到,我声明 TypeScript 不会在错误函数中构建 没有 return 语句.我收到错误:Supplied parameters do not match any signature of call target: Call signatures of types '(result: MyApp.Models.User) =&gt; MyApp.Models.User' and '(promiseValue: MyApp.Models.User) =&gt; ng.IHttpPromise&lt;{}&gt;' are incompatible: Type 'MyApp.Models.User' is missing property 'success' from type 'ng.IHttpPromise&lt;{}&gt; 这就是为什么我在Finally 中有return,所以它满足了这两个要求。我该如何解决这个问题?
    • 我相信您可以在throw error 下添加return null 以使TypeScript 快乐。当然它会在它返回之前抛出,所以这很好。
    猜你喜欢
    • 1970-01-01
    • 2014-08-24
    • 2018-12-06
    • 2018-01-27
    • 2013-11-23
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多