Вызывайте функцию обещания несколько раз, пока не будет выполнено условие другой функции обещания
У меня есть следующий код: 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 ответ
Когда вы объявляете 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
вместо тайм-аутов ванильного JavaScript, так что любые изменения в $scope
не происходит вне цикла дайджеста Angular.