我想要返回一个$ q实例,这样如果客户不打电话,那么'使用拒绝处理程序,然后运行默认处理程序。
E.g。假设默认值为alert(1)
然后mypromise.then(function(result){...})
会提醒1,但mypromise.then(null, function(reason){alert(2)})
会提醒2
答案 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处理程序的方法是reduced到the halting problem。这是impossible。 <子>(2)子>
一般而言 - 无法检测.catch
处理程序是否附加到承诺。
反应良好!像许多问题一样,这个问题理论上不可能,但在实践中很容易解决实际案例。这里的关键是启发式:
如果错误处理程序没有附加在微任务中(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;被捕获。