我了解,通常情况下then()
,使用诺言时,只是将延续代码附加在调用和链接行为上。
但是,我要开始一个承诺包装的异步调用,然后分别开始一个3秒钟,$timeout()
以便可以执行UI操作,仅当原始的承诺尚未完成时。(我预计这只会在连接速度慢,3G上的移动设备等上发生)
有了诺言,我是否可以在不阻塞或等待的情况下检查它是否完整?
我了解,通常情况下then()
,使用诺言时,只是将延续代码附加在调用和链接行为上。
但是,我要开始一个承诺包装的异步调用,然后分别开始一个3秒钟,$timeout()
以便可以执行UI操作,仅当原始的承诺尚未完成时。(我预计这只会在连接速度慢,3G上的移动设备等上发生)
有了诺言,我是否可以在不阻塞或等待的情况下检查它是否完整?
Answers:
我想这是在Angular的最新版本中添加的,但现在承诺中似乎有一个$$ state对象:
var deferred = $q.defer();
console.log(deferred.promise.$$state.status); // 0
deferred.resolve();
console.log(deferred.promise.$$state.status); //1
如评论中所述,不建议这样做,因为在升级Angular版本时可能会中断。
$$...
不应使用属性。升级到较新版本的Angular时可能会冒险...
inspect
功能。因此,对于我们的Angular开发人员来说,没有汁液。Promise原型根本没有它。
我认为您最好的选择是(不修改Angular源并提交拉取请求),如果承诺没有解决,则保留一个本地标志。每次您设置您感兴趣的诺言时都将其重置,并then()
在原始诺言中将其标记为已完成。在$timeout
then()
检查标志中,以了解原始承诺是否已经解决。
像这样:
var promiseCompleted = false;
promise.then(function(){promiseCompleted=true;})
$timeout(...).then(function(){if(!promiseCompleted)doStuff()})
Kris Kowal的实现包括检查承诺状态的其他方法,但$q
不幸的是Angular的实现似乎不包括这些方法。
正如@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);
我遇到了类似的问题,需要检查诺言是否已返回。因为$watch
即使未定义新值和旧值,AngularJS的函数也会在渲染页面时记录更改,因此我必须检查是否有任何值得存储在外部模型中的数据。
绝对是hack,但是我这样做:
$scope.$watch('userSelection', function() {
if(promiseObject.hasOwnProperty("$$v"){
userExportableState.selection = $scope.userSelection;
}
};
我知道这$$v
是AngularJS使用的内部变量,但它已经非常可靠,可以作为对我们的已解决承诺的指标。谁知道当我们升级到AngularJS 1.2时会发生什么:-//我看不到$q
1.2文档中有任何改进的提法,但是也许有人会写一个替代服务,其功能集更接近Q。