javascript 在 catch 之后执行 then

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28446869/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 08:59:22  来源:igfitidea点击:

Executing then after catch

javascriptangularjsangular-promise

提问by TGH

I have the following fiddle: http://jsfiddle.net/thelgevold/3uv9nnjm/6/

我有以下小提琴:http: //jsfiddle.net/thelgevold/3uv9nnjm/6/

angular.module('hello',[]).controller('helloController',function($q){

    console.clear();
    function someService(){
       var deferred = $q.defer();
       deferred.reject({e:'error'}); 
       return deferred.promise;
    } 

    function callService(){
        return someService().then(function(obj){
           console.log('first then');
        }).
        catch(function(e){
            console.log('error1');
            var deferred = $q.defer();
            deferred.reject({e:'error'}); 
            return deferred.promise;
        });
    }

    callService().catch(function(e){
      console.log('error2');
    }).then(function(e){
      console.log('second then');
    });

});

It's essentially just a quick $q promise POC. My question is: Why does the last then clause get called when the promise is rejected? The output is as follows:

它本质上只是一个快速的 $q 承诺 POC。我的问题是:当承诺被拒绝时,为什么会调用最后一个 then 子句?输出如下:

error1

错误1

error2

错误2

second then

第二然后

I understand why error1/error2 are printed, but I thought the second then string should not be printed since the promise was rejected. I thought it would omit "second then" for the same reason the "first then" is omitted. Any thoughts?

我明白为什么会打印 error1/error2,但我认为第二个 then 字符串不应该被打印,因为 promise 被拒绝了。我认为它会省略“second then”,原因与省略“first then”的原因相同。有什么想法吗?

回答by JLRishe

Before I get started, don't do this:

在我开始之前,不要这样做:

var deferred = $q.defer();
deferred.reject({e:'error'}); 
return deferred.promise;

Do this:

做这个:

return $q.reject({e:'error'});

Or preferably, this:

或者最好是这样:

return $q.reject(new Error('error'));

Beware the deferred antipattern.

当心延迟反模式。

Now, for the answer to your question.

现在,回答你的问题。



.catch().catch()你的电话后,callService()callService()正赶上错误,而不是产生新的错误。它基本上“处理”了错误,并且.then().then()可以自由调用以下处理程序。

The synchronous code equivalent of your example would be:

与您的示例等效的同步代码是:

function someService() {
  throw { e: 'error' };
}

function callService() {
  try {
    var obj = someService();
    console.log('first then');
  } catch (e) {
    console.log('error1');
    throw { e: 'error' };
  }
}

var e;
try {
  e = callService();
} catch (e) {
  console.log('error2');
}

console.log('second then');

I think that if you look at it this way, it makes perfect sense.

我认为,如果你这样看,它是完全有道理的。

The relevant text in the Promises/A+ spec is here. For all intents and purposes, you can view the catchhandler as the same thing as an onRejectedhandler:

Promises/A+ 规范中的相关文本在这里。出于所有意图和目的,您可以将catch处理程序视为与处理程序相同的事物onRejected

2.2.7. then must return a promise [3.3].

promise2 = promise1.then(onFulfilled, onRejected);

2.2.7.1. If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).

2.2.7. 然后必须返回一个承诺 [3.3]。

promise2 = promise1.then(onFulfilled, onRejected);

2.2.7.1. 如果 onFulfilled 或 onRejected 返回值 x,则运行 Promise Resolution Procedure [[Resolve]](promise2, x)。

Basically, your onRejectedhandler is "returning" the value undefined, so the promise produced by catch()resolves with the value undefined.

基本上,您的onRejected处理程序正在“返回” value undefined,因此由catch()value产生的承诺会解析undefined