admin管理员组文章数量:1290221
I'm trying to use the AngularJS promise/then with a recursive function. But the then-function is not called (none of the error-, success-, notify-callbacks gets called).
Here is my code:
recursive function
loadSection2 = function() {
var apiURL = "http://..."
var deferred = $q.defer();
$http({
method: "GET",
url: apiURL
}).success(function(result, status, headers, config) {
console.log(result);
loadCount++;
if(loadCount < 10) {
newSectionArray.push(result);
loadSection2();
} else {
loadCount = 0;
deferred.resolve();
return deferred.promise;
}
}).error(function() {
return deferred.reject();
});
deferred.notify();
return deferred.promise;
};
then
loadSection2().then(function() {
console.log("NEW SECTIONS LOADED, start adding to document");
addContent();
}, function() {
console.log("ERROR CALLBACK");
}, function() {
console.log("NOTIFY CALLBACK");
}).then(function() {
loadScrollActive = false;
});
I think, the then has to get the first notify-callback at least. But there is no callback. Is then not working with recursive function?
I'm trying to use the AngularJS promise/then with a recursive function. But the then-function is not called (none of the error-, success-, notify-callbacks gets called).
Here is my code:
recursive function
loadSection2 = function() {
var apiURL = "http://..."
var deferred = $q.defer();
$http({
method: "GET",
url: apiURL
}).success(function(result, status, headers, config) {
console.log(result);
loadCount++;
if(loadCount < 10) {
newSectionArray.push(result);
loadSection2();
} else {
loadCount = 0;
deferred.resolve();
return deferred.promise;
}
}).error(function() {
return deferred.reject();
});
deferred.notify();
return deferred.promise;
};
then
loadSection2().then(function() {
console.log("NEW SECTIONS LOADED, start adding to document");
addContent();
}, function() {
console.log("ERROR CALLBACK");
}, function() {
console.log("NOTIFY CALLBACK");
}).then(function() {
loadScrollActive = false;
});
I think, the then has to get the first notify-callback at least. But there is no callback. Is then not working with recursive function?
Share Improve this question edited Dec 16, 2013 at 9:28 Manishearth 16.2k8 gold badges60 silver badges76 bronze badges asked Dec 16, 2013 at 9:27 FauphiFauphi 3581 gold badge2 silver badges11 bronze badges 4 |3 Answers
Reset to default 24EDIT - 11/11/2015 There is a much cleaner way if you don't care about notify:
loadSection2 = function (){
var apiURL = "http://..."
return $http.get(apiURL)
.then(function(response){
loadCount++;
if (loadCount < 10) {
newSectionArray.push(response.data);
return loadSection2();
}
loadCount = 0;
});
};
Old answer available here:
You could continuously pass the promise all the way through.
loadSection2 = function(deferred) {
if(!deferred){
deferred = $q.defer();
}
var apiURL = "http://..."
$http({
method: "GET",
url: apiURL
}).success(function(result, status, headers, config) {
console.log(result);
loadCount++;
if(loadCount < 10) {
newSectionArray.push(result);
loadSection2(deferred);
} else {
loadCount = 0;
deferred.resolve();
return deferred.promise;
}
}).error(function() {
return deferred.reject();
});
deferred.notify();
return deferred.promise;
};
I wanted to make a solution that doesn't pass "deferred" variable around and even though I wouldn't say it is a better approach, it works and I learned a from it (jsfiddle).
19/Aug/14 - Updated the code to a much shorter version by removing the creation of another promise in f1(). I hope that it is clear how it relates to the original question. If it isn't let me know in a comment.
f1().then(function() {
console.log("done");
});
function f1(counter) {
if (!counter) {
counter = 0;
}
counter++;
console.log(counter);
return asyncFunc().then(function() {
if (counter < 10) {
return f1(counter);
} else {
return;
}
});
}
function asyncFunc() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve();
}, 100);
return deferred.promise;
}
Fauphi,
Recursion is totally viable but not a particularly "promisy" approach.
Given that you have deferreds/promises available, you can dynamically build a .then()
chain, which delivers a promise of a populated array.
function loadSection2(arr) {
return $http({
method: "GET",
url: "http://..."
}).then(function(result, status, headers, config) {
console.log(result);
arr.push(result);
return arr;//make the array available to the next call to loadSection2().
}, function() {
console.log("GET error");
return $q.defer().resolve(arr).promise;//allow the chain to continue, despite the error.
//or I think $q's .then() allows the much simpler form ...
//return arr; //allow the chain to continue, despite the error.
});
};
var newSectionPromise = $q.defer().resolve([]).promise;//note that the deferred is resolved with an anonymous new array.
//Now we build a .then() chain, ten long, ...
for (var i=0; i<10; i++) {
newSectionPromise = newSectionPromise.then(loadSection2);
}
// ... and do something with the populated array when the GETs have done their thing.
newSectionPromise().then(function(arr) {
console.log(arr.length + " new sections loaded, start adding to document");
addContent(arr);
}, function() {
console.log("ERROR CALLBACK");
}).then(function() {
loadScrollActive = false;
});
untested
What was newSectionArray
is now created anonymously and passed down the .then()
chain regardless of success/failure of the individual GETs, emerging as arr
in the final .then's success handler, where it is passed to addContent()
. This avoids the need for member newSectionArray
in the outer scope.
Rearranging slightly, loadSection2
could be made anonymous, further reducing the number of members added to the outer scope.
The need for an explicit notification disappears as :
- there is no longer a master deferred to be notified
console.log(result);
in the GET success handler provides all the notification necessary.
本文标签: javascriptAngularJSpromise with recursive functionStack Overflow
版权声明:本文标题:javascript - AngularJS, promise with recursive function - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738314103a2074196.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
notify
doesn't work like you think. I have a open issue for that in angular repo -> github.com/angular/angular.js/issues/5277 – Rifat Commented Dec 16, 2013 at 9:37