是否可以将多个错误处理程序附加到单个承诺中?

时间:2015-11-02 21:34:42

标签: javascript angularjs

我一直在为项目使用angular的$ http服务。在完成项目之前,我注意到.success.error回调已被弃用。 现在我们有.then.catch条款,很好。

我有一个服务,它包含对某些API的调用。在该服务内部,我想在未经授权的请求中“安装”默认错误处理程序。我曾经这样做过:

post = function(encodedData ,headers ,url ) {
    headers.Accept = '*/*';

        this.setAutentication();

    return $http({
      'url': url,
      'method': 'POST',
      'data': encodedData,
      'headers': headers
    }).error( this.callUnauthorizedHandler.bind(this) );
  };

如您所见,我返回$ http promise,并附带了错误处理程序。由于.error回调返回原始承诺,所以一切都像魅力一样。现在我必须首先将promise保存到变量,使用catch附加错误处理程序然后返回promise。 这不是一个大问题,但我觉得没有办法将几个“错误”处理程序附加到单个promise中,所以如果我添加另一个catch子句,我想我会覆盖已安装的那个。它是否正确?管理这个的正确方法是什么?我所读到的关于承诺的所有内容都没有说明这个想法是有效还是绝对愚蠢。

编辑:

我找到了这个答案:https://stackoverflow.com/a/22415684/1734815 似乎我必须从我的“默认”错误处理程序中抛出错误,如果它现在能够自己处理错误,但我不确定这一点。

1 个答案:

答案 0 :(得分:2)

承诺的工作方式是在第一次捕获后错误传播停止。

somePromise().then( /* ... */ ).catch( function () {
    console.log( 'Error 1' );
} ).catch( function () {
    // Will not execute
    console.log( 'Error 2' );
} );



// On the other hand, in this case...
var p = somePromise().then( /* ... */ );

p.catch( function () {
    console.log( 'Error 1' );
} );

p.catch( function () {
    // Will execute
    console.log( 'Error 2' );
} );

这是因为catch返回的promise实际上是一个不同的对象。

var p = somePromise.then( /*...*/ );

var x = p.catch( /*...*/ );

p === x // False

这意味着,每当您拨打.then时,.catch都是.then( null, fn )的简写,您就会返回新的承诺。

所以,让我们说你想拦截一​​个错误并仍然让它传播。有两种方式。

示例1

var p = somePromise();

p.catch( /*...*/ );

return p;

这是有效的,因为我们将多个侦听器附加到相同的承诺。所以,即使有人打电话给另一个.catch,它仍会抓住它。 缺点:有人调用一个.then后(因此在链中创建一个新的承诺实例),下面的任何.catch都不会捕获错误(因为它正在在链条中被追上了。)

示例2 首选

return somePromise().then( /*...*/ ).catch( function ( reason ) {
   this.callUnauthorizedHandler( reason );

   // Here we can leverage the fact that all promises 
   // return a new promise, so we can just forge a promise 
   // that will reject right away with the value we want
   return $q.reject( reason );
} );