我有一个问题我正在解析一些json文件到一个html页面而Urls在另一个json文件中:我有一个很大的问题,因为没有检测到错误,我得到一个空页面,所以在调试时使用一些警报我发现我的控制器得到一个空列表: 我应该按照警报的顺序接听电话:
alert(tab[i]+ " 1");
alert(list+ " 2");
alert(list+ " 3");
但是我收到了这个订单:
alert(tab[i]+ " 1");
alert(list+ " 3");
alert(list+ " 2");
这是我的代码
app.factory('myapp', ['$http', function($http) {
function getLists() {
$http.get('url').success(function(data) {
return data;
var tab = [];
for (i = 0; i < (data).length; i++) {
tab.push(data[i]);
}
var list = [];
for(i=0; i<tab.length; i++){
alert(tab[i]+ " 1");
$http.get(tab[i]).then(function(res) {
list.push(res.data);
alert(list+ " 2");
});
alert(list+" 3");
}
return list;
})
}
return {
getLists: getLists
};
])};
答案 0 :(得分:2)
由于您尝试在for循环中进行异步请求,因此异步请求的性质导致返回顺序完全不一致。您必须使用$q
之类的内容确保退货订单,这样您就可以按顺序解决承诺。
app.factory('listsFactory', ['$http', '$q', function($http, $q) {
function getLists() {
return $http.get('url').success(function(tabs) {
return $q.all(tabs.map(function(tab) {
return $http.get(tab)
.then(function(res) {
return res.data;
});
}));
})
}
return {
getLists: getLists
};
}]);
然后,像这样使用getLists
:
app.controller('myController', ['listsFactory', function(listsFactory) {
listsFactory.getLists().then(function(lists) {
// do something with lists
// $scope.something = lists;
});
}]);
稍微分解一下:似乎你设置标签的第一个循环是多余的,因为回调arg包含你想要的数据(除非我错过了什么)。所以只需命名arg tabs
,然后将一个新的promises数组传递给$q.all
并返回。调用getLists
时,它将按顺序返回一个包含每个promise值的数组的promise。
阐述success
回调arg:
$http.get('url').success(function(data) {
var tab = [];
for (i = 0; i < (data).length; i++) {
tab.push(data[i]);
}
...
您在此处所做的事情是不必要的,因为您有效地克隆data
,以便它是一个新数组,具有相同的值,但命名为tabs
。您可以通过命名success
回调参数tabs
来避免这种情况。这将包含与您的版本相同的完全相同的数据,并且还可以减少冗余。
答案 1 :(得分:0)
由于您的格式化,我不确定所有问题,但似乎您的匿名成功处理程序的第一行返回数据,然后您继续执行可能永远不会执行的for循环,因为您返回了该函数的值。
答案 2 :(得分:0)
alert(tab[i]+ " 1");
alert(list+ " 3");
alert(list+ " 2");
您按照以下顺序获得订单,因为alert(list + " 2")
在$http
回拨函数中是异步的。所以当你回调函数被调用时,它是不能保证的。
然而,只要循环完成,就会执行alert(list + " 3")
。即,进行for循环中的异步调用但不回调该函数。
这就是您在alert(list + " 3")
之前获得alert(list + " 2")
的原因。
app.factory('myapp', ['$http', '$q', function($http, $q) {
function getLists() {
$http.get('url').success(function(data) {
return data;
var tab = [];
for (i = 0; i < (data).length; i++) {
tab.push(data[i]);
}
var list = [];
var promises = [];
for(i=0; i < tab.length; i++){
promises.push($http.get(tab[i]));
}
$q.all(promises).then(function(data) {
angular.forEach(data, function(value, key) {
this.push(value);
alert(list + " 2");
}, list);
alert(list + " 3");
});
return list;
})
}
return {
getLists: getLists
};
])};
答案 3 :(得分:0)
我发现问题的解决方案很简单,我只需要在getLists函数中声明list并在第一个http.get之外添加返回列表:
app.factory('myapp', ['$http', function($http) {
function getLists() {
var list = [];
$http.get('url').success(function(data) {
return data;
var tab = [];
for (i = 0; i < (data).length; i++) {
tab.push(data[i]);
}
for(i=0; i<tab.length; i++){
alert(tab[i]+ " 1");
$http.get(tab[i]).then(function(res) {
list.push(res.data);
alert(list+ " 2");
});
alert(list+" 3");
}
})
return list;
}
return {
getLists: getLists
};
])};