在 catch 之后执行 then [英] Executing then after catch

查看:101
本文介绍了在 catch 之后执行 then的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下小提琴: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.我的问题是:当承诺被拒绝时,为什么最后一个 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:

错误1

错误 2

然后第二次

我明白为什么会打印 error1/error2,但我认为第二个 then 字符串不应该被打印,因为 promise 被拒绝了.我认为它会省略second then",原因与省略first 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?

推荐答案

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

Before I get started, don't do this:

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

这样做:

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

或者最好是这样:

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

注意延迟反模式.

现在,回答您的问题.


在您调用 callService() 之后的 .catch() 正在捕获错误并且不会产生新的错误.它基本上处理"了错误,并且可以自由调用以下 .then() 处理程序.

Now, for the answer to your question.


The .catch() after your call to callService() is catching the error and not producing a new error. It has essentially "handled" the error, and the following .then() handler is free to be called.

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

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.

Promises/A+ 规范中的相关文本是此处.出于所有意图和目的,您可以将 catch 处理程序视为与 onRejected 处理程序相同的内容:

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

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

2.2.7. then must return a promise [3.3].

promise2 = promise1.then(onFulfilled, onRejected);

2.2.7.1.如果 onFulfilled 或 onRejected 返回值 x,则运行 Promise 解析过程 [[Resolve]](promise2, x).

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

基本上,您的 onRejected 处理程序正在返回"值 undefined,因此 catch() 生成的承诺将使用值 <代码>未定义.

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

这篇关于在 catch 之后执行 then的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆