我有以下代码:http://jsfiddle.net/kyy4ey10/4/
$scope.count = 0;
function getActiveTasks() {
var deferred = $q.defer();
setTimeout(function() {
$scope.count++;
deferred.resolve();
},1000)
return deferred.promise;
}
// i want to put this inside the function, but it doesn't work
var deferred = $q.defer();
function callPromise() {
getActiveTasks().then(function(){
if($scope.count < 5){
callPromise();
}
else{
deferred.resolve()
}
})
return deferred.promise;
}
callPromise().then(function(){
$scope.count = "done"
});
如果我把:
var deferred = $q.defer();
在callPromise()
函数内,$scope.count
无法解析为“完成”。
如何更改我编写这两个函数的方式,然后调用callPromise()
,这样我就不必将var deferred = $q.defer();
放在外面了?
答案 0 :(得分:2)
当您在外部声明deferred
并递归调用您的函数时,最里面的递归调用将从外部解析deferred.promise
。当它在里面宣布时,只有最内在的承诺得到解决(但它永远不会被返回)。考虑这个小提琴,它说明了一个类似的变量范围问题:
https://jsfiddle.net/sg6odtof/
var counter = 5;
var a = "outside";
function b() {
//If you uncomment this, the behavior of b is different.
//var a = "inside";
if (counter > 0) {
counter--;
b();
}
return a;
}
alert(b());
我猜你不喜欢这个变量以外的变量;因此我认为你想要做的是让外部递归返回内部递归的承诺。
http://jsfiddle.net/pLns9mjw/1/
function callPromise() {
return getActiveTasks().then(function(){
if($scope.count < 5) {
return callPromise();
}
});
}
另外,不确定你真正想要做什么考虑$q.all
接受一系列承诺并在所有承诺完成后解决。只要您的任务事先知道,如果您只是想在他们完成所有工作时通知,这很容易。
如果正在进行的任务是动态的,可能会被添加,你可以$q.all
他们,并检查是否在完成该承诺之前还剩下任何任务,直到没有剩下。
如果您只想做一个持续状态,当您处于特定阈值时向用户报告时,您的超时方法就可以了。
请注意,您应该使用$timeout
而不是vanilla JavaScript超时,以便$scope
的任何更改都不会在Angular的摘要周期之外发生。