如何检查是否已解决Angular $ q promise

bla*_*ter 83 promise angularjs q

我理解通常只会then()在使用promises时附加带有调用和链行为的延续代码.

但是,我想启动一个承诺包装的异步调用,然后单独启动3秒,$timeout()这样我就可以采取UI操作,只要原始承诺尚未完成.(我预计这只会发生在慢速连接,3G上的移动设备等)

有了承诺,我可以检查它是否完整而没有阻塞或等待?

par*_*ent 46

我想这是在Angular的最新版本中添加的,但现在似乎在承诺上有一个$$状态对象:

 var deferred = $q.defer();
 console.log(deferred.promise.$$state.status); // 0
 deferred.resolve();
 console.log(deferred.promise.$$state.status); //1 
Run Code Online (Sandbox Code Playgroud)

如评论中所述,不建议这样做,因为在升级Angular版本时它可能会中断.

  • Angular docs说不应该使用`$$ ...`属性.升级到较新版本的Angular时可能会有风险...... (24认同)
  • 太糟糕了Angular在银盘上提供了私有变量.:( (7认同)
  • 另见:http://stackoverflow.com/questions/27039771/q-js-is-it-possible-to-know-if-a-promise-has-resolved-rejected-or-not (2认同)
  • 但是...... Angular没有实现`inspect`功能.所以Angular开发者没有果汁.承诺原型根本没有它. (2认同)

sha*_*ain 36

我认为你最好的选择是(不修改Angular源并提交拉取请求)是保留一个本地标志,如果承诺已经解决.每次设置您感兴趣的承诺时重置它,并then()在原始承诺中将其标记为完整.在$timeout then()检查标志时,知道原始承诺是否已经解决.

像这样的东西:

var promiseCompleted = false;
promise.then(function(){promiseCompleted=true;})
$timeout(...).then(function(){if(!promiseCompleted)doStuff()})
Run Code Online (Sandbox Code Playgroud)

Kris Kowal的实现包括用于检查承诺状态的其他方法,但$q不幸的是,Angular的实现不包括这些.

  • 最好在这里使用.finally().上面提供的代码只会将promiseCompleted标志标记为true,如果它已成功解析. (9认同)

Ber*_*rgi 8

这似乎是不可能的,正如@shaunhusain已经提到过的那样.但也许没有必要:

// shows stuff from 3s ahead to promise completetion, 
// or does and undoes it in one step if promise completes before
$q.all(promise, $timeout(doStuff, 3000)).then(undoStuff);
Run Code Online (Sandbox Code Playgroud)

或者更好:

var tooSlow = $timeout(doStuff, 3000);
promise.always(tooSlow.cancel);
Run Code Online (Sandbox Code Playgroud)