$q:默认拒绝处理程序 [英] $q: default reject handler

查看:19
本文介绍了$q:默认拒绝处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想返回一个 $q 实例,以便如果客户端不使用拒绝处理程序调用then",则运行默认的一个.

I want to return a $q instance so that if clients don't call 'then' with a reject handler, then a default one runs.

例如假设默认是 alert(1)

然后 mypromise.then(function(result){...}) 会警告 1 但 mypromise.then(null, function(reason){alert(2)}) 将警告 2

Then mypromise.then(function(result){...}) will alert 1 but mypromise.then(null, function(reason){alert(2)}) will alert 2

推荐答案

让我们假设有一种方法可以做到这一点.

所以我们有一个神奇的机器,它总能找出 .then 是否使用函数的第二个参数来调用特定的 promise.

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.

您可以将包含大量代码 P (1) 的整个程序转换为:

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:

如果微任务中没有附加错误处理程序(Angular 中的摘要) - 永远不会附加任何错误处理程序,我们可以改为触发默认处理程序.

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.

大致是:你从不 .then(null, function(){}) 异步.Promise 是异步解析的,但处理程序通常是同步附加的,所以这很好用.

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 添加拒绝跟踪时 - 有几个人建议,如果一个承诺在没有 catch 的情况下被拒绝,那么整个应用程序可能会终止.所以要格外小心:)

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 的代码而不运行它就足以检测 myPromise 是否获得拒绝处理程序.正式地说,我们将 P 和其他终止形式中的每个 return 更改为 return myPromise.then(null, function(){}) 而不是简单地将其放入结束.这样就捕获了条件".

(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屋!

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