Angular $q 返回承诺多次 $http 调用
Angular $q returning promise multiple $http calls
我正在处理一个 $http 调用,该调用循环遍历一个对象中的多个 api 和 return 中的所有数据。我通常会在调用 $http 时准备好解决的承诺。类似这样:
function getAllData(api) {
return $http({
method: 'GET',
url: '/api/' + api
})
.then(sendResponseData)
.catch (sendGetVolunteerError);
}
我的当前函数遍历每个 api 并将 api 中的每个对象推入一个数组,然后将其推入一个整体数组。我有这个功能,return创建一个多维数组,需要将其展平。
我想 return 这个承诺,但是 return 正在 undefined
。这是我到目前为止所拥有的?有没有更好的方法来解决这个问题?
数据服务:
function getSearchData() {
return {
loadDataFromUrls: function () {
var apiList = ["abo", "ser", "vol", "con", "giv", "blo", "par"];
var deferred = $q.defer();
var log = [];
angular.forEach(apiList, function (item, key) {
var logNew = [];
$http({
method: 'GET',
url: '/api/' + item
}).then(function (response) {
angular.forEach(response.data, function (item, key) {
this.push(item);
}, logNew);
return logNew;
});
this.push(logNew);
}, log);
$q.all(log).then(
function (results) {
deferred.resolve(
JSON.stringify(results))
},
function (errors) {
deferred.reject(errors);
},
function (updates) {
deferred.update(updates);
});
return deferred.promise;
}
};
};
控制器:
function getSearchData(){
return dataService.getSearchData.loadDataFromUrls;
}
$scope.searchData = getSearchData();
您应该在 $q
中添加一个承诺列表(不是像您的代码中那样已解决的承诺),这是一个 $promise service
示例:
var firstPromise = service1.getMethod1().$promise;
var secondPromise = service2.getMethod2().$promise;
$q.all([firstPromise, secondPromise]).then(function(dataList){
// dataList[0] will be result of `firstPromise`
// dataList[1] will be result of `secondPromise`
});
如果您有任意一组 api 调用,我会这样做:
function getSearchData(){
var deferred = $q.defer();
var noOfCalls = apiList.length;
var results = [];
var called = 0;
angular.forEach(apiList, function(item, key) {
$http.get(url).then(function(result){
results.push(result);
called++;
if(called == noOfCalls){
deferred.resolve(results);
}
})
});
return deferred.promise;
}
但是,如果您知道每个 api 调用代表什么,那么以这种方式使用 $.all 会更好
function search1(){
return $http.get(search1Url).then(function(result){
// do something to it
return result;
});
}
function search2(){
return $http.get(search2Url).then(function(result){
// do something to it
return result;
});
}
function search3(){
return $http.get(search3Url).then(function(result){
// do something to it
return result;
});
}
function search4(){
return $http.get(search4Url).then(function(result){
// do something to it
return result;
});
}
function getSearchResult(){
return $q.all([search1(), search2(), search3(), search4()]).then(function(results){
// OPTIONAL aggregate results before resolving
return results;
});
}
$q.all
和 map
函数是您需要的:
function getSearchData() {
return {
// returns a promise for an object like:
// { abo: resultFromAbo, ser: resultFromSer, ... }
loadDataFromUrls: function () {
var apiList = ["abo", "ser", "vol", "con", "giv", "blo", "par"];
return $q.all(apiList.map(function (item) {
return $http({
method: 'GET',
url: '/api/' + item
});
}))
.then(function (results) {
var resultObj = {};
results.forEach(function (val, i) {
resultObj[apiList[i]] = val.data;
});
return resultObj;
});
}
};
}
我正在处理一个 $http 调用,该调用循环遍历一个对象中的多个 api 和 return 中的所有数据。我通常会在调用 $http 时准备好解决的承诺。类似这样:
function getAllData(api) {
return $http({
method: 'GET',
url: '/api/' + api
})
.then(sendResponseData)
.catch (sendGetVolunteerError);
}
我的当前函数遍历每个 api 并将 api 中的每个对象推入一个数组,然后将其推入一个整体数组。我有这个功能,return创建一个多维数组,需要将其展平。
我想 return 这个承诺,但是 return 正在 undefined
。这是我到目前为止所拥有的?有没有更好的方法来解决这个问题?
数据服务:
function getSearchData() {
return {
loadDataFromUrls: function () {
var apiList = ["abo", "ser", "vol", "con", "giv", "blo", "par"];
var deferred = $q.defer();
var log = [];
angular.forEach(apiList, function (item, key) {
var logNew = [];
$http({
method: 'GET',
url: '/api/' + item
}).then(function (response) {
angular.forEach(response.data, function (item, key) {
this.push(item);
}, logNew);
return logNew;
});
this.push(logNew);
}, log);
$q.all(log).then(
function (results) {
deferred.resolve(
JSON.stringify(results))
},
function (errors) {
deferred.reject(errors);
},
function (updates) {
deferred.update(updates);
});
return deferred.promise;
}
};
};
控制器:
function getSearchData(){
return dataService.getSearchData.loadDataFromUrls;
}
$scope.searchData = getSearchData();
您应该在 $q
中添加一个承诺列表(不是像您的代码中那样已解决的承诺),这是一个 $promise service
示例:
var firstPromise = service1.getMethod1().$promise;
var secondPromise = service2.getMethod2().$promise;
$q.all([firstPromise, secondPromise]).then(function(dataList){
// dataList[0] will be result of `firstPromise`
// dataList[1] will be result of `secondPromise`
});
如果您有任意一组 api 调用,我会这样做:
function getSearchData(){
var deferred = $q.defer();
var noOfCalls = apiList.length;
var results = [];
var called = 0;
angular.forEach(apiList, function(item, key) {
$http.get(url).then(function(result){
results.push(result);
called++;
if(called == noOfCalls){
deferred.resolve(results);
}
})
});
return deferred.promise;
}
但是,如果您知道每个 api 调用代表什么,那么以这种方式使用 $.all 会更好
function search1(){
return $http.get(search1Url).then(function(result){
// do something to it
return result;
});
}
function search2(){
return $http.get(search2Url).then(function(result){
// do something to it
return result;
});
}
function search3(){
return $http.get(search3Url).then(function(result){
// do something to it
return result;
});
}
function search4(){
return $http.get(search4Url).then(function(result){
// do something to it
return result;
});
}
function getSearchResult(){
return $q.all([search1(), search2(), search3(), search4()]).then(function(results){
// OPTIONAL aggregate results before resolving
return results;
});
}
$q.all
和 map
函数是您需要的:
function getSearchData() {
return {
// returns a promise for an object like:
// { abo: resultFromAbo, ser: resultFromSer, ... }
loadDataFromUrls: function () {
var apiList = ["abo", "ser", "vol", "con", "giv", "blo", "par"];
return $q.all(apiList.map(function (item) {
return $http({
method: 'GET',
url: '/api/' + item
});
}))
.then(function (results) {
var resultObj = {};
results.forEach(function (val, i) {
resultObj[apiList[i]] = val.data;
});
return resultObj;
});
}
};
}