在 catch 之后执行 then [英] Executing then after catch
问题描述
我有以下小提琴: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屋!