8

我正试图找出一个好的方式来表达“做所有这些事情,但如果其中任何一个失败,请保释”

我现在拥有的:

var defer = $q.defer();

this
    .load( thingy ) // returns a promise

    .then( this.doSomethingA.bind( this ) )
    .then( this.doSomethingB.bind( this ) )
    .then( this.doSomethingC.bind( this ) )
    .then( this.doSomethingD.bind( this ) )

    .then( function(){
        defer.resolve( this );
    } );
    ;

return defer.promise;

我最终想要的是以某种方式捕获该链上的任何错误,以便我可以将其传递给defer上面的承诺。我并不特别关心语法是否与我上面的相似。

或者即使有人可以告诉我如何停止上述链条。

4

6 回答 6

6

您可以通过在任何 then 回调中返回被拒绝的承诺来停止 angularjs 链。

load()
.then(doA)
.then(doB)
.then(doC)
.then(doD);

其中doAdoBdoCdoD可以有这样的逻辑:

var doA = function() {
    if(shouldFail) {
        return $q.reject();
    }
}
于 2015-07-20T19:01:18.477 回答
3

我只是偶然发现了这一点,并意识到所有这些答案都已经过时了。对于碰巧找到此帖子的任何人,这是处理此问题的正确方法。

// Older code
return this.load(thing)
  .then(this.doA, $q.reject)
  .then(this.doB, $q.reject)
  .then(this.doC, $q.reject)
  .then(this.doD, $q.reject)
  .then(null, $q.reject);


// Updated code
// Returns the final promise with the success handlers and a unified error handler
return this.load(thing)
  .then(this.doA)
  .then(this.doB)
  .then(this.doC)
  .then(this.doD)
  .catch(this.handleErrors); // Alternatively, this can be left off if you just need to reject the promise since the promise is already rejected.
  // `.catch` is an alias for `.then(null, this.handleErrors);`
于 2015-07-29T06:55:20.187 回答
2

您应该能够通过以下方式做同样的事情:

var defer = $q.defer();

this
    .load( thingy ) // returns a promise

    .then( this.doSomethingA.bind( this ), $q.reject )
    .then( this.doSomethingB.bind( this ), $q.reject )
    .then( this.doSomethingC.bind( this ), $q.reject )
    .then( this.doSomethingD.bind( this ), $q.reject )

    .then( defer.resolve.bind( defer, this ), defer.reject.bind( defer ) );
    ;

return defer.promise;
于 2013-10-23T17:59:28.180 回答
0

看起来这个用例已经被预期并使用 $q.reject(reason) 解决了

于 2013-10-23T15:58:36.243 回答
0

好的,这可行,但我不喜欢它......等待更好的东西:)

仅仅为了立即拒绝它而创建一个承诺似乎很肮脏

myApp
    .factory( 'chainReject', [ '$q', function( $q ){
        return function( err ){
            var defer = $q.defer();
            defer.reject( err );

            return defer.promise;
        }
    } ] );

...

var defer = $q.defer();

this
    .load( thingy ) // returns a promise

    .then( this.doSomethingA.bind( this ), chainReject )
    .then( this.doSomethingB.bind( this ), chainReject )
    .then( this.doSomethingC.bind( this ), chainReject )
    .then( this.doSomethingD.bind( this ), chainReject )

    .then( defer.resolve.bind( defer, this ), defer.reject.bind( defer ) );
    ;

return defer.promise;
于 2013-05-30T23:38:04.137 回答
0

处理此问题并解决问题的最佳方法是 .catch 块。在任何你想杀死承诺链的 .then 块中,是的,使用:

 return $q.reject();

但是像这样扩展它......

 return $q.reject(new Error('Error Message Here'));

现在在 catch 方法中你将拥有这个

 .catch(function(err) {
     console.log(err); //This will log the above 'Error Message Here'
 });

现在我们以应处理的方式正确地抛出和处理 promise 错误。

于 2016-02-04T14:45:52.190 回答