如何检查角度$ q诺言是否已解决


84

我了解,通常情况下then(),使用诺言时,只是将延续代码附加在调用和链接行为上。

但是,我要开始一个承诺包装的异步调用,然后分别开始一个3秒钟,$timeout()以便可以执行UI操作,仅当原始的承诺尚未完成时。(我预计这只会在连接速度慢,3G上的移动设备等上发生)

有了诺言,我是否可以在不阻塞或等待的情况下检查它是否完整?


2
我在angular中对此问题打开了一个问题,并得到了有用的答复github.com/angular/angular.js/issues/8307#issuecomment-49903373
derekdreery 2014年

Answers:


46

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

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

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


25
Angular文档说$$...不应使用属性。升级到较新版本的Angular时可能会冒险...
hgoebl

7
太糟糕了,Angular在一个银色的盘子上提供了它的私有变量。:(
杰克逊


2
但是,但是... Angular没有实现该inspect功能。因此,对于我们的Angular开发人员来说,没有汁液。Promise原型根本没有它。
罗伯特·科里特尼克'16

36

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

像这样:

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

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


9
最好在这里使用.finally()。如果成功解决,上面提供的代码只会将promiseCompleted标志标记为true。
Karanvir Kang

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);

也许更好:

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

1

我遇到了类似的问题,需要检查诺言是否已返回。因为$watch即使未定义新值和旧值,AngularJS的函数也会在渲染页面时记录更改,因此我必须检查是否有任何值得存储在外部模型中的数据。

绝对是hack,但是我这样做:

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

我知道这$$v是AngularJS使用的内部变量,但它已经非常可靠,可以作为对我们的已解决承诺的指标。谁知道当我们升级到AngularJS 1.2时会发生什么:-//我看不到$q1.2文档中有任何改进的提法,但是也许有人会写一个替代服务,其功能集更接近Q。


谢谢,但是有比使用“私人”成员更好的选择。
杰克逊

0

我不知道您的确切情况,但是更典型的是在进行异步调用(并生成Promise)后立即设置超时。

setTimeout()只要该语句与异步调用位于同一事件线程中,您就不必担心竞争效应的可能性。由于javascript严格是单线程的,因此.then()可以保证在以后的事件线程中触发promise的回调。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.