$ q:默认拒绝处理程序

时间:2015-02-22 21:56:30

标签: javascript angularjs promise angular-promise

我想要返回一个$ q实例,这样如果客户不打电话,那么'使用拒绝处理程序,然后运行默认处理程序。

E.g。假设默认值为alert(1)

然后mypromise.then(function(result){...})会提醒1,但mypromise.then(null, function(reason){alert(2)})会提醒2

1 个答案:

答案 0 :(得分:7)

我们假设有办法做到这一点。

所以我们有一个神奇的机器,可以随时找出是否使用函数第二个参数调用.then来表示特定的承诺。

那又怎样?

所以你可以检测出是否有人:

myPromise.then(..., function(){ F(); });

随时随地都可以。并将G()作为默认操作。

和...?

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

var myPromise = $q.reject();
P; // inline the program's code
myPromise.then(null, function(){}); // attach a handler

很好,所以我可以这样做,所以?

好吧,现在我们的神奇机器可以采用任意程序P并检测myPromise是否添加了拒绝处理程序。现在,当且仅当P不包含无限循环(即它停止)时,才会发生这种情况。因此,我们检测是否添加了catch处理程序的方法是reducedthe halting problem。这是impossible。 <子>(2)

一般而言 - 无法检测.catch处理程序是否附加到承诺。

停止使用mumbu-jumbo,我想要一个解决方案!

反应良好!像许多问题一样,这个问题理论上不可能,但在实践中很容易解决实际案例。这里的关键是启发式:

  

如果错误处理程序没有附加在微任务中(Angular中的摘要) - 没有连接任何错误处理程序,我们可以触发默认处理程序。

粗略地说:你从不 .then(null, function(){})是异步的。 Promise是异步解析的,但处理程序通常是同步连接的,所以这很好用。

// 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的情况下拒绝承诺,那么整个应用程序可能会终止。所以要格外小心:)

(1)假设P不包含变量myPromise,如果它将myPromise重命名为P不包含的内容。

(2)当然 - 可以说,读取P的代码并且不运行它以便检测myPromise得到拒绝处理程序就足够了。我们正式说我们将P中的每个return和其他形式的终止更改为return myPromise.then(null, function(){}),而不是简单地将其置于最后。这样的条件&#34;条件性&#34;被捕获。