多次调用promise函数,直到从另一个promise函数满足条件

时间:2016-05-07 03:41:45

标签: javascript angularjs recursion promise angular-promise

我有以下代码: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();放在外面了?

1 个答案:

答案 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的摘要周期之外发生。