对递归数据结构的承诺
a promise for a recursive data structure
我想在调用控制器之前解析递归数据结构,但我正在为如何执行此操作而苦苦挣扎。
我当前的代码如下所示:
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
);
};
我能否以某种方式 "collect" sub.loadChildren() 返回的承诺并将它们合并?
是的,您可以使用 $q.all
将承诺收集到一个承诺中,该承诺在列表中的每个承诺都已解决时解决。
var promises = []
angular.forEach(subs, function(sub) {
promises.push(sub.loadChildren());
region.children.push(sub);
});
$q.all(promises).then(function(values) {
// Finished
})
$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
您可以将当前函数替换为创建初始数组的函数,然后将其传递给执行实际工作的原始函数的修改版本:
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
使用 $q.all
合并承诺集合,并确保 return 它们用于 链接 。
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);
);
};
因为调用承诺的 .then
方法 return 是一个新的派生承诺,所以很容易创建承诺链。可以创建任意长度的链,并且由于一个 promise 可以用另一个 promise 解决(这将进一步推迟其解决),因此可以 pause/defer 在链中的任何点解决 promise。这使得实现强大的 API 成为可能。1
有关详细信息,请参阅 AngularJS $q service API Reference -- chaining promises.
请注意 $q.all
没有弹性 。如果其中一个承诺被拒绝,$q.all
将解决第一个错误被拒绝的问题。
我想在调用控制器之前解析递归数据结构,但我正在为如何执行此操作而苦苦挣扎。
我当前的代码如下所示:
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
);
};
我能否以某种方式 "collect" sub.loadChildren() 返回的承诺并将它们合并?
是的,您可以使用 $q.all
将承诺收集到一个承诺中,该承诺在列表中的每个承诺都已解决时解决。
var promises = []
angular.forEach(subs, function(sub) {
promises.push(sub.loadChildren());
region.children.push(sub);
});
$q.all(promises).then(function(values) {
// Finished
})
$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
您可以将当前函数替换为创建初始数组的函数,然后将其传递给执行实际工作的原始函数的修改版本:
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
使用 $q.all
合并承诺集合,并确保 return 它们用于 链接 。
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);
);
};
因为调用承诺的 .then
方法 return 是一个新的派生承诺,所以很容易创建承诺链。可以创建任意长度的链,并且由于一个 promise 可以用另一个 promise 解决(这将进一步推迟其解决),因此可以 pause/defer 在链中的任何点解决 promise。这使得实现强大的 API 成为可能。1
有关详细信息,请参阅 AngularJS $q service API Reference -- chaining promises.
请注意 $q.all
没有弹性 。如果其中一个承诺被拒绝,$q.all
将解决第一个错误被拒绝的问题。