Javascript 停止AngularJS承诺链

Javascript 停止AngularJS承诺链,javascript,angularjs,Javascript,Angularjs,我在想一个好办法,说“做所有这些事情,但万一其中任何一件失败就保释” 我现在所拥有的: var defer=$q.defer(); 这 .load(thingy)//返回一个承诺 .然后(这个.doSomethingA.绑定(这个)) .then(this.doSomethingB.bind(this)) .then(this.doSomethingC.bind(this)) .then(this.doSomethingD.bind(this)) .然后(函数(){ 推迟.解决(这个问题); }

我在想一个好办法,说“做所有这些事情,但万一其中任何一件失败就保释”

我现在所拥有的:

var defer=$q.defer();
这
.load(thingy)//返回一个承诺
.然后(这个.doSomethingA.绑定(这个))
.then(this.doSomethingB.bind(this))
.then(this.doSomethingC.bind(this))
.then(this.doSomethingD.bind(this))
.然后(函数(){
推迟.解决(这个问题);
} );
;
回报、承诺;
我最终想要的是以某种方式捕获该链上的任何错误,以便我可以将其传递给上面的
延迟
承诺。我并不特别关心语法是否与上面的语法相似


或者,即使有人可以告诉我如何停止上面的链。

好的,这很有效,但我不喜欢它。。。等待更好的东西:)

仅仅为了立即拒绝而做出承诺似乎是肮脏的

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;

看起来像这个用例,使用$q.reject(reason)解决了这个问题。

您应该能够通过以下方式完成同样的任务:

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;

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

load()
.then(doA)
.then(doB)
.then(doC)
.then(doD);
其中doA、doB、doC、doD可以有如下逻辑:

var doA = function() {
    if(shouldFail) {
        return $q.reject();
    }
}

我只是偶然发现了这一点,并意识到所有这些答案都非常过时。这里是正确的方法来处理这一点,为任何人,碰巧找到这篇文章

// 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);`

处理此问题和捕获问题的最佳方法是.catch块。在任何内部。然后阻止你想要杀死承诺链,是的,使用:

 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'
 });

现在,我们以承诺失败应该被处理的方式正确地抛出和处理承诺错误。

@user2246674——拒绝承诺似乎并不会停止这条链,但下一个承诺只是继续。我不知道我在想什么。这是一个可怕的承诺失败的例子!拧紧
延迟
,只需
返回
这个。加载(…)。然后(A)。然后(B)。然后(C)。然后(D)链!此答案使用反模式,并导致用户重复错误处理。
.catch
在angular的
$q
中不存在。当问到这个问题时:)@zyklus,你是对的,但是
。catch
只是
的别名。然后(null,fn)
。它当时应该是有效的。它不用于传递错误,也就是说,它只会捕获来自上一个
然后
的错误,这就是为什么我在下面写了所有链拒绝废话。如果是这样的话,那么使用
$q.reject
作为每个
的第二个参数就正确了。我将把我的答案作为一个更新版本,正确处理承诺,而接受的答案仍然使用反模式。不会停止链。Catch返回一个承诺。+1它为我做的是
return
部分
return$q.reject()
。大量的搜索导致了各种不同的方式,但是真正返回$q.reject()而不是仅仅调用它才是杀死链的原因。特别是如果您尝试执行的操作不是HTTP失败,而是“失败”,即模型返回预期的负面响应。另一种停止链的方法是,假设您希望显示链执行期间发生的错误,您可以
抛出新错误()
返回被拒绝的承诺不会停止供应链。