异步的forEach AngularJS后回调 [英] callback after async forEach AngularJS
问题描述
我如何添加一个回调函数异步后foreach循环?
的下面是一些更好的背景:的
$ scope.getAlbums =功能(用户,回调){
$ scope.albumsList.forEach(函数(OBJ,I){
$ scope.getAlbum(用户,obj.id,功能(价值){
$ scope.albums.push(值);
});
});
// 回电话(); ???
};$ scope.getAlbums('guy123',函数(){
// forEach循环中全部完成!
的console.log($ scope.albums)
});
控制器:
.controller('过滤器',['$范围,Imgur',函数($范围,Imgur){ $ scope.getAlbum =功能(用户ID,回调){
Imgur.album.get({用户:用户ID:ID},
功能(值){
返回回调(value.data);
}
);
} $ scope.getAlbums =功能(用户,回调){
//这个foreach循环结束回调函数?
//请求是异步...
$ scope.albumsList.forEach(函数(OBJ,I){
$ scope.getAlbum(用户,obj.id,功能(价值){
$ scope.albums.push(值);
});
});
};
)]};
服务:
.factory('Imgur',函数($资源){
返回{
专辑:$资源('https://api.imgur.com/3/account/:user/album/:id')
}
});
安德鲁说 $ Q
的使用和递延对象应该让你实现你的目标。
您想要使用 $ q.all()
这将确保所有你的诺言对象的都解决了,然后你可以叫你回电。然后()
函数MyCtrl($范围,$ Q $ HTTP){ $ scope.albumsList = [{
ID:1,
名称:11
},{
ID:2,
名称:22
}
];
$ scope.albums = [];
$ scope.getAlbum =功能(用户ID,回调){
返回$ http.get(https://api.imgur.com/3/account/+用户+/专辑/+ ID).success(
功能(值){
返回回调(value.data);
}
);
}
$ scope.getAlbums =功能(用户,回调){
VAR舞会= [];
$ scope.albumsList.forEach(函数(OBJ,I){
prom.push($ scope.getAlbum(用户,obj.id,功能(价值){
$ scope.albums.push(值);
}));
});
$ q.all(PROM)。然后(函数(){
回电话();
});
};
$ scope.getAlbums('guy123',函数(){
警报($ scope.albums.length);
});
}
作品,但不与 $ HTTP
要求
通过递延对象,你获得对一个承诺,你可以改变连续访问则()
通话在一起。当您解决延迟对象它将执行的foreach,然后执行您的回调您所提供的功能。我尝试了一下进一步简化你的榜样,所以它会在工作的jsfiddle
函数MyCtrl($范围,$ HTTP,$ Q){ $ scope.albumsList = [{
ID:1,
名称:11
},{
ID:2,
名称:22
}];
$ scope.albums = [];
$ scope.getAlbums =功能(用户,回调){
变种推迟= $ q.defer();
VAR承诺= deferred.promise;
promise.then(函数(){
$ scope.albumsList.forEach(函数(OBJ,I){
$ scope.albums.push(OBJ);
});
})。然后(函数(){
回电话();
});
deferred.resolve();
};
$ scope.getAlbums('guy123',函数(){
警报($ scope.albums.length);
});
}
How do I add a callback function after an async forEach Loop?
Here is some better context:
$scope.getAlbums = function(user, callback) {
$scope.albumsList.forEach(function (obj, i) {
$scope.getAlbum(user, obj.id, function(value){
$scope.albums.push(value);
});
});
// callback(); ???
};
$scope.getAlbums('guy123', function(){
// forEach loop is all done!
console.log($scope.albums)
});
Controller:
.controller('Filters', ['$scope','Imgur', function($scope, Imgur) {
$scope.getAlbum = function(user, id, callback) {
Imgur.album.get({user:user, id:id},
function(value) {
return callback(value.data);
}
);
}
$scope.getAlbums = function(user, callback) {
// Callback function at end of this forEach loop?
// Request is async...
$scope.albumsList.forEach(function (obj, i) {
$scope.getAlbum(user, obj.id, function(value){
$scope.albums.push(value);
});
});
};
)]};
Service:
.factory('Imgur', function($resource) {
return {
album : $resource('https://api.imgur.com/3/account/:user/album/:id')
}
});
As Andrew said usage of $q
and the deferred object should allow you to accomplish your goal.
You want to use $q.all()
This will make sure all of your promise objects are resolved and then you can call your call back in .then()
function MyCtrl($scope, $q, $http) {
$scope.albumsList = [{
id: 1,
name: "11"
}, {
id: 2,
name: "22"
}
];
$scope.albums = [];
$scope.getAlbum = function(user, id, callback) {
return $http.get("https://api.imgur.com/3/account/" + user + "/album/" + id).success(
function(value) {
return callback(value.data);
}
);
}
$scope.getAlbums = function (user, callback) {
var prom = [];
$scope.albumsList.forEach(function (obj, i) {
prom.push($scope.getAlbum(user, obj.id, function(value){
$scope.albums.push(value);
}));
});
$q.all(prom).then(function () {
callback();
});
};
$scope.getAlbums('guy123', function () {
alert($scope.albums.length);
});
}
Works but not with $http
calls
With the deferred object you gain access to a promise where you can change successive then()
calls together. When you resolve the deferred object it will execute the foreach and then execute your call back function you supplied. I tried to simplify your example a bit further so it would work in jsfiddle.
function MyCtrl($scope, $http, $q) {
$scope.albumsList = [{
id: 1,
name: "11"
}, {
id: 2,
name: "22"
}];
$scope.albums = [];
$scope.getAlbums = function (user, callback) {
var deferred = $q.defer();
var promise = deferred.promise;
promise.then(function () {
$scope.albumsList.forEach(function (obj, i) {
$scope.albums.push(obj);
});
}).then(function () {
callback();
});
deferred.resolve();
};
$scope.getAlbums('guy123', function () {
alert($scope.albums.length);
});
}
A bit more reading on deferred and promises.
这篇关于异步的forEach AngularJS后回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!