[英]$q.all With Recursion?
我有一个进行递归调用的函数。 结构看起来像这样:
var getData = function(data){
makeDbCall().then(function(response){
if(response.something === someCondition){
foreach(object in response)
getData(object ); //calls itself over and over
}
}
)
};
一般的想法是(避免成为话题),例如,获得一个城市中的所有酒店,这些酒店中的所有房间,这些房间中的所有家具,等等。一个普通的$ q.all foreach调用就是这样 -函数定义:
var promises = [];
然后返回$ q.all:
return $q.all(promises);
我的问题是,我不知道从哪里返回$ q.all-如果我从“ getData”返回$ q.all,则它将在递归的第一次迭代中返回,并且(据我所知)可能不包含后续迭代最初的呼叫会在新呼叫推送之前解决。
如果我在getData()
调用之后将其返回,则会遇到相同的问题,因为众所周知,除非我们推迟执行,否则javascript会继续运行而不等待调用。
我意识到这个问题是含糊的,我的含糊答复完全可以。 我只是想看看我是否缺少绝对基本的东西,或者这是不可能的。 (我确实知道如何以一种非常肮脏的方式进行操作,但是我真的很想以某种方式使用$ q.all)。
我通过嵌套promise解析尝试了一些事情,如下所示:
function getData(){
return new Promise((resolve, reject)){
for(let item of response){
getData(item).then((res)=>{
resolve(res);
},(err)=>{
reject(err);
});
}
}
}
诀窍是尽可能使用诺言。 这样,只有在解决孩子问题后,您才能获得最高级别的承诺,也可以进行异步递归。
您可能要做的一件事是在原始的Promise数组中链接Promise,并使用map来获取数组中每个元素的Promise,即考虑此片段
function getHotels(city) { return ajaxPromise ... }
function getRooms(hotel) { ... }
function getFurniture(room) { ... }
function showUI(furniture) { ... }
getHotels(city).then(function(hotels) {
return $q.all(hotels.map( h => getRooms(h)))
}).then(function(hotelRooms) {
return $q.all(hotelRooms.map (hr => getFurniture(hr)))
}).then(showUI)
对于初学者 - -
不推荐使用此方法
app.factory('json',function($q,$http){
return function(files){
var promises = [];
angular.forEach(files, function(file){
var deffered = $q.defer();
$http({
url : file,
method: 'GET'
}).success(function(data){
deffered.resolve(data);
}).error(function(error){
deffered.reject();
});
promises.push(deffered.promise);
})
return $q.all(promises);
}
});
$http
方法的.success
和.error
方法已弃用 。 有关更多信息,请参见《 AngularJS $ http服务API参考》 。
首选方式是:
app.factory('json',function($q,$http){
return function(files){
var promises = [];
angular.forEach(files, function(file){
var promise =
$http({
url : file,
method: 'GET'
})
promises.push(promise);
})
return promises;
}
});
然后,您可以分别处理每个返回的$q.all
或使用$q.all
。 请注意, $q.all
没有弹性 。 第一个承诺拒绝将跳过.then
方法,只有先拒绝将被捕获.catch
方法。
var promiseList = json(files);
$q.all(promiseList).then (function (responseList) {
//executes only if all promises ok
$scope.dataList = doSomethingWith(responseList);
}). catch (error) { function (error)
//executes with first error
//log error
});
单独处理承诺:
promiseList[0].then (function (result) {
//save data
$scope.dataList[0] = result.data;
}).catch (function (error) {
//log error
});
请注意.then
和.catch
方法比返回数据不同.success
和.error
方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.