Javascript $q:默认拒绝处理程序

Javascript $q:默认拒绝处理程序,javascript,angularjs,promise,angular-promise,Javascript,Angularjs,Promise,Angular Promise,我想返回一个$q实例,这样,如果客户端没有使用拒绝处理程序调用“then”,那么将运行一个默认实例 例如,假设默认设置为警报(1) 然后mypromise.Then(函数(结果){…})将向1发出警报,但mypromise.Then(null,函数(原因){alert(2)})将向2发出警报。 因此,我们有一个神奇的机器,它总是能够找出。然后用一个函数第二个参数调用,以确定是否有特定的承诺 那又怎么样? 因此,您可以检测是否有人: myPromise.then(..., function(){

我想返回一个$q实例,这样,如果客户端没有使用拒绝处理程序调用“then”,那么将运行一个默认实例

例如,假设默认设置为
警报(1)

然后
mypromise.Then(函数(结果){…})
将向1发出警报,但
mypromise.Then(null,函数(原因){alert(2)})
将向2发出警报

。 因此,我们有一个神奇的机器,它总是能够找出
。然后用一个函数第二个参数调用
,以确定是否有特定的承诺

那又怎么样? 因此,您可以检测是否有人:

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处理程序的方法是。是的。(二)

因此,一般来说,不可能检测到
.catch
处理程序是否附加到承诺

别胡闹了,我要一个解决办法! 反应很好!像许多问题一样,这个问题在理论上是不可能的,但在实践中很容易解决。这里的关键是一个启发:

如果一个错误处理程序没有附加到一个微任务中(角度摘要),那么就永远不会附加错误处理程序,我们可以触发默认处理程序

这大概是:您永远不会异步地
。然后(null,function(){})
。承诺是异步解析的,但是处理程序通常是同步附加的,所以这很好

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

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


(2) 当然,我们可以说,读取p的代码,而不是运行它来检测
myPromise
获取拒绝处理程序就足够了。正式地说,我们将P和其他终止形式中的每个
return
都更改为
returnmypromise.then(null,function(){})
,而不是简单地将其放在末尾。通过这种方式捕获“条件性”。

不要认为promises语法范围,第二个参数期望为failure callback
$q。最后可以使用
,但不能使用它进行分支。一种方法是使用像bluebird这样的promise库,它内置了此功能(onPossiblyUnhandledRejection)-也就是说,这个用例听起来很奇怪-需要详细说明吗?这个用例是,如果错误没有得到处理,我想显示一条消息。本质上,我希望在主循环中有类似于在其他体系结构中看到的“一网打尽”的东西。即使需要异步附加,也可以始终同步添加
promise.catch(function(){})
,因为它只会创建一个保证始终满足的新分支。如果我有两个承诺链呢?一个挨着另一个。第一个有一个处理程序。第二个没有。解析时,第一个会成功,但第二个不会成功。由于所有“thens”都是同步执行的,因此不会触发默认操作。