我想在调用控制器之前解决递归数据结构,但我正在努力解决这个问题。
我目前的代码如下:
region.loadChildren = function() {
region.children = [];
return region.resource.all('children').getList().then(function(subs) {
angular.forEach(subs, function(sub) {
sub.loadChildren();
region.children.push(sub);
});
}, errorCallback
);
};
我可以以某种方式"收集" sub.loadChildren()返回的promise并将它们组合起来?
答案 0 :(得分:2)
是的,您可以使用$q.all
将承诺收集到单个承诺中,该承诺会在列表中的每个承诺解决后解决。
var promises = []
angular.forEach(subs, function(sub) {
promises.push(sub.loadChildren());
region.children.push(sub);
});
$q.all(promises).then(function(values) {
// Finished
})
答案 1 :(得分:1)
$ q.all是你的解决方案 -
region.loadChildren = function() {
region.children = [];
return region.resource.all('children').getList().then(function(subs) {
var promises = subs.map(subs, function(sub) {
var promise = sub.loadChildren();
region.children.push(sub);
return promise;
});
var allPromisesInOnePromise = $q.all(promises); // a regular promise which will resolve when all of the promises will resolve
}, errorCallback
);
};
你可以在这里阅读更多关于promises的内容以及这里的$ q.all函数 - https://docs.angularjs.org/api/ng/service/$q
答案 2 :(得分:1)
使用$q.all
合并承诺集合,并确保返回 链接。
region.loadChildren = function() {
//return for chaining
return region.resource.all('children').getList().then(function(subs) {
var children = [];
angular.forEach(subs, function(sub) {
var p = sub.loadChildren();
children.push(p);
});
//return for chaining
return $q.all(children);
);
};
因为调用promise的.then
方法会返回一个新的派生promise,所以很容易创建一个promise链。可以创建任何长度的链,并且由于可以使用另一个承诺(将进一步推迟其解析)来解决承诺,因此可以在链中的任何点暂停/推迟承诺的解析。这使得实现强大的API成为可能。 1
有关详细信息,请参阅AngularJS $q service API Reference -- chaining promises.
请注意$q.all
不具弹性。如果其中一个承诺被拒绝,$q.all
将解决第一个错误。
答案 3 :(得分:0)
您可以将当前函数替换为创建承诺将被累积到的初始数组的函数,然后将其传递给执行实际工作的原始函数的修改版本:
region.loadChildren = function() {
var tmp = [];
this.loadChildrenHelper(tmp);
this.children = tmp;
}
region.loadChildrenHelper = function(accum) {
return region.resource.all('children').getList().then(function(subs) {
angular.forEach(subs, function(sub) {
sub.loadChildrenHelper(accum);
accum.push(sub);
});
}, errorCallback
);
};
然后在结果数组上使用$q.all