$ Q:默认情况下拒绝处理程序 [英] $q: default reject handler
问题描述
我要回一个$ Q实例,因此,如果客户不叫,然后以拒绝处理,然后一个默认的运行。
I want to return a $q instance so that if clients don't call 'then' with a reject handler, then a default one runs.
例如。假设默认是警报(1)
然后 mypromise.then(功能(结果){...})
将提醒1,但 mypromise.then(NULL,函数(原因){警报(2)})
将提醒2
Then mypromise.then(function(result){...})
will alert 1 but mypromise.then(null, function(reason){alert(2)})
will alert 2
推荐答案
因此,我们有一个神奇的机器,总是可以找出是否。然后
被调用函数的第二个参数为特定的承诺或没有。
Let's assume there was a way to do that.
So we have a magical machine that can always find out if .then
is called with a function second argument for a specific promise or not.
所以,你可以,如果有人做了检测:
So you can detect if someone did:
myPromise.then(..., function(){ F(); });
目前从任何地方在任何时间任何一点。并有 G()
作为默认操作。
At any point from anywhere at any time. And have G()
as a default action.
您可以将含有大量的code P <子>(1)的整个程序,并转换了code为:
You could take a whole program containing lots of code P (1) and convert that code to:
var myPromise = $q.reject();
P; // inline the program's code
myPromise.then(null, function(){}); // attach a handler
太好了,这样我就可以做到这一点,这样的吗?
好了,现在我们的神奇的机器可以任意程序P,并检测是否 myPromise
不得不拒绝处理程序添加到它。现在,这种情况发生,当且仅当 P
不包含一个无限循环(即其停止)。因此,我们是否曾经加入一个catch处理程序检测方法是降低来的停机问题。这是不可能。 <子>(2)
Great, so I can do that, so?
Well, now our magical machine can take an arbitrary program P and detect if myPromise
had a rejection handler added to it. Now this happens if and only if P
does not contain an infinite loop (i.e. it halts). Thus, our method of detecting if a catch handler is ever added is reduced to the halting problem. Which is impossible. (2)
所以一般 - 这是不可能检测一个 .catch
的处理程序是不断连接到一个承诺
So generally - it is impossible to detect if a .catch
handler is ever attached to a promise.
反应良好!像许多的问题这一个的理论上的不可能的,但在实践中很容易解决的实际案例。这里的关键是一个启发式的:
Good response! Like many problems this one is theoretically impossible but in practice easy enough to solve for practical cases. The key here is a heuristic:
如果一个错误处理程序是不是一个microtask内连接(在角消化) - 没有错误处理程序不断连接,我们可以发射默认的处理程序,而不是
If an error handler is not attached within a microtask (digest in Angular) - no error handlers are ever attached and we can fire the default handler instead.
这大致是:你的从不的。然后(NULL,函数(){})
异步。承诺以异步方式解决,但处理程序通常同步连接所以这个工作得很好。
That is roughly: You never .then(null, function(){})
asynchronously. Promises are resolved asynchronously but the handlers are usually attached synchronously so this works nicely.
// keeping as library agnostic as possible.
var p = myPromiseSource(); // get a promise from source
var then = p.then; // in 1.3+ you can get the constructor and use prototype instead
var t = setTimeout(function(){ // in angular use $timeout, not a microtask but ok
defaultActionCall(p);// perform the default action!
});
// .catch delegates to `.then` in virtually every library I read so just `then`
p.then = function then(onFulfilled, onRejected){
// delegate, I omitted progression since no one should use it ever anyway.
if(typeof onRejected === "function"){ // remove default action
clearTimeout(t); // `timeout.cancel(t)` in Angular
}
return then.call(this, onFulfilled, onRejected);
};
是这样吗?
好吧,我只想补充一点,在需要这种极端的做法的情况下并不多见。在讨论中添加跟踪拒绝向IO - 几个人建议,如果一个承诺是没有捕捉拒绝
那么整个应用程序应该终止可能。所以要格外小心:)
Is that all?
Well, I just want to add that cases where this extreme approach is needed are rare. When discussing adding rejection tracking to io - several people suggested that if a promise is rejected without a catch
then the whole app should likely terminate. So take extra care :)
(1)假设P没有包含一个可变myPromise,如果它命名myPromise东西P没有包含
(2)当然 - 可以说,这是足以读取P的code,而不是为了检测运行 myPromise
得到一个拒绝处理。在形式上,我们说,我们改变P中每个收益
和其他形式终止于返回myPromise.then(NULL,函数(){})
,而不是简单地把它进行到底。这样的条件被捕获。
(2) Of course - one can say that it is enough to read the code of P and not run it in order to detect myPromise
gets a rejection handler. Formally we say that we change every return
in P and other forms of termination to a return myPromise.then(null, function(){})
instead of simply putting it in the end. this way the "conditionality" is captured.
这篇关于$ Q:默认情况下拒绝处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!