问题 捕获后执行


我有以下小提琴: 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');
    });

});

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

ERROR1

误差2

第二个

我理解为什么会打印error1 / error2,但我认为第二个字符串不应该被打印,因为承诺被拒绝了。我认为它会省略“第二个然后”,出于同样的原因,“第一个然后”被省略。 有什么想法吗?


6488
2018-02-11 04:56


起源



答案:


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

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

做这个:

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

或者最好是这样:

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

小心延迟反模式。

现在,回答你的问题。


.catch() 打电话给你 callService() 正在捕获错误并且不会产生新错误。它基本上“处理”了错误,以及以下内容 .then() 处理程序可以自由调用。

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

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

我认为,如果以这种方式看待它,它就非常有意义。

Promises / A +规范中的相关文本是 这里。出于所有意图和目的,您可以查看 catch 处理程序与a相同 onRejected 处理:

2.2.7。然后必须回复承诺[3.3]。

promise2 = promise1.then(onFulfilled, onRejected);

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

基本上,你的 onRejected handler正在“返回”该值 undefined,所以产生的承诺 catch() 用价值解决 undefined


13
2018-02-11 05:29



谢谢!这是有道理的 - TGH


答案:


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

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

做这个:

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

或者最好是这样:

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

小心延迟反模式。

现在,回答你的问题。


.catch() 打电话给你 callService() 正在捕获错误并且不会产生新错误。它基本上“处理”了错误,以及以下内容 .then() 处理程序可以自由调用。

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

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

我认为,如果以这种方式看待它,它就非常有意义。

Promises / A +规范中的相关文本是 这里。出于所有意图和目的,您可以查看 catch 处理程序与a相同 onRejected 处理:

2.2.7。然后必须回复承诺[3.3]。

promise2 = promise1.then(onFulfilled, onRejected);

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

基本上,你的 onRejected handler正在“返回”该值 undefined,所以产生的承诺 catch() 用价值解决 undefined


13
2018-02-11 05:29



谢谢!这是有道理的 - TGH