我要回一个$ 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:默认情况下拒绝处理程序
发布评论