如何检查一个有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被保证在后面的事件线程中触发。