对递归数据结构的承诺

时间:2016-03-22 14:39:56

标签: angularjs recursion angular-promise

我想在调用控制器之前解决递归数据结构,但我正在努力解决这个问题。

我目前的代码如下:

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并将它们组合起来?

4 个答案:

答案 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

相关问题