我试图从不同的数据库中获取两个结果集。第二个结果取决于从第一个结果集中检索的参数。我想确保在继续之前返回两个结果集。看看其他一些问题,我想也许这会奏效:
app.factory('myService',['$http','$q',function ($http, $q){
function getDetails(scope){
var paths = [];
return $q.all([
$http.post('getdetails.php',{begDate:scope.begDate, endDate:scope.endDate})
.then(function(response) {
angular.forEach(response.data,function(table,key){
angular.forEach(table, function(row,key){
paths.push(row.CURRENT_PATH);
})
})
return response;
})
,
$http.post('coordtest.php', {paths: paths})
.then(function(response) {
return response;
})
]);
}
return {
getDetails: getDetails
};
}]);
但是当路径仍为空时,两者的结果都会返回?
答案 0 :(得分:1)
在您从第一个请求中检索数据之前,您似乎无法发出第二个请求。但是,您希望返回第二个请求的承诺。这是可能的,但$q.all
不太适合(对于可以一次发送所有请求的情况,它更有用。)
您似乎真正想要的是有一个请求( B )依赖于另一个请求的结果( A ),但要返回的承诺B 以便可以使用其结果。使用$q.defer
使用以下模式创建包装器承诺是可能的:
var response = $q.defer();
$http.get('a').success(function(data){
$http.get('b', data).then(response.resolve, response.reject);
});
return response.promise;
在您的代码中,这可能类似于:
app.factory('myService',['$http','$q',function ($http, $q){
function httpGetDetails(scope){
return $http.post('getdetails.php',{
begDate:scope.begDate,
endDate:scope.endDate
});
}
function parseDetails(response){
return response.reduce(function(parsedResults, table){
var paths = table.map(function(row){
return row.CURRENT_PATH;
});
return parsedResults.concat(paths);
}, []);
}
function getDetails(scope){
var result = $q.defer();
var getDetailsRequest = httpGetDetails(scope);
getDetailsRequest.success(function(response){
var paths = parseDetails(response);
$http.post('coordtest.php', {paths: paths})
.success(result.resolve) // Both requests succeeded
.error(result.reject); // coordtest.php failed
});
// getdetails.php failed.
// Consider sending params that make it more obvious which failed
getDetailsRequest.error(result.reject);
return result.promise;
}
return {
getDetails: getDetails
};
}]);
显然,你可以稍微清理一下这些功能,但它是链接承诺的简单要点。
我们的想法是创建一个运行时间更长的承诺,并根据内部(第二个)请求的结果手动解决它。这类似于从coordtest
工厂返回myService
响应,除了它是可行的(您无法同步返回异步函数中的$http
承诺,因此您可以创建并创建一个提前掩盖承诺)。