如何检查一个有angular度的$ q承诺是否被解决

我明白,通常在使用promise的时候,只需要使用then()调用和连锁行为来附加延续代码。

但是,我想要启动承诺封装的asynchronous调用,然后单独启动一个3秒的$timeout()以便我可以执行UI操作,只有在原始承诺尚未完成的情况下。 (我预计这只会发生在连接速度慢,3G上的移动设备等)

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

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

  var deferred = $q.defer(); console.log(deferred.promise.$$state.status); // 0 deferred.resolve(); console.log(deferred.promise.$$state.status); //1 

正如在评论中指出的那样,不build议这样做,因为在升级您的Angular版本时它可能会中断。

我认为你最好的select是,(不修改angular源和提交拉请求)是保留一个本地标志,如果承诺已经解决。 每次设置你感兴趣的承诺时重置它,并在原始承诺的then()标记为完整。 在$timeout then()检查标志,以知道如果原来的承诺已经解决或没有。

像这样的东西:

 var promiseCompleted = false; promise.then(function(){promiseCompleted=true;}) $timeout(...).then(function(){if(!promiseCompleted)doStuff()}) 

Kris Kowal的实现包括检查promise的状态的其他方法,但是看起来Angular的$q的实现不幸的不包括这些。

这似乎是不可能的,因为@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); 

或者也许更好:

 var tooSlow = $timeout(doStuff, 3000); promise.always(tooSlow.cancel); 

我有一个类似的问题,我需要检查一个承诺是否已经返回。 由于AngularJS的$watch函数在渲染页面时会注册一个变化,即使新旧值都是未定义的,我也要检查是否有任何值存储在我的外部模型中。

这绝对是一个黑客,但我这样做:

 $scope.$watch('userSelection', function() { if(promiseObject.hasOwnProperty("$$v"){ userExportableState.selection = $scope.userSelection; } }; 

我知道$$v是AngularJS使用的一个内部variables,但它作为我们已经解决的承诺的一个指标已经相当可靠了。 谁知道当我们升级到AngularJS 1.2时会发生什么: – 我没有看到在1.2版本中提到对$q的改进,但也许有人会写一个更接近于Q的更好的function集。

我不知道你的确切情况,但是在进行asynchronous调用(并生成承诺)之后立即放置一个超时是比较典型的。

提供setTimeout()语句与asynchronous调用在同一事件线程中,您不必担心竞争效果的可能性。 由于javascript是严格单线程的,promise的.then()callback被保证在后面的事件线程中触发。