递归承诺创建树 [英] Recursive promises to create tree

查看:46
本文介绍了递归承诺创建树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当节点元素传递给它时,树api返回子元素.

A tree api returns childrens when node element is passed to it.

我首先传递根节点,然后根据返回的节点,如果它们的 hasChildren 参数为true,则将它们全部递归地返回.

I pass the root node first and then on the basis of the nodes returned I pass all of them back recursively, if they have hasChildren parameter true.

有没有办法知道函数何时完成树的创建.

Is there a way to know when the function has finished creating the tree.

function recursivelyFetchChildren(id, selectedAsset, parentId){
    return ajaxCall(id, selectedAsset, parentId)
    .then(function(data){
        //collects all childs in childs array
        childs.push(data);
        for(var i=0; i<data.length; i++){
            if(data[i].HasChildren){
                return recursivelyFetchChildren(id,selectedAsset,data[i].Id);
            }else{
                //this return statement prematurely completes the promise
                return data[i];
            }
        }
    });
}

recursivelyFetchChildren(id, selectedAsset, parentId).then(function(){
    print(childs)  //prints the childs before all the promises have resolved
});

任何人都可以建议一种方法,让我可以使recursivelyFetchChildren函数等待呈现完整的树吗?

Can anyone suggest an approach where I can make the recursivelyFetchChildren function wait for rendering the complete tree?

推荐答案

采用另一种方法,并返回一个在所有子项都被解析后已解析的函数.

Go the other way, and return a function that is resolved when all of its children are resolved.

{
  id: "123",
  data: {
    children: [
      { id: "234", value: 2, data: { children: [] } },
    ]
  }
}


const loadData = node => getData(`/url/${node.id}`).then(data => {
  return loadChildren(data.hasChildren ? data.children : [])
    .then(children => {
      data.children = children;
      node.data = data;
      return node;
    });
});
const loadChildren = children => Promise.all(children.map(loadData));

因为我要返回并链接承诺,所以我返回的最外面的一个不会解析,直到最里面的一个完成.

Because I am returning and chaining promises, the outermost one that I return won't resolve, until the inner-most one is finished.

就个人而言,我可能会构建一个新节点,而不是修改我已有的节点,但这完全是另一回事.

Personally, I would be likely to build a new node, rather than modify the one that I had, but that's a different matter altogether.

相互递归:两个相互调用的函数.

Mutual Recursion: two functions that call one another.

function a () { return b(); }
function b () { return a(); }

如果有一棵树,其中每个根都有一个子数组,则可以编写两个函数来回跳动:一个用于处理节点,一个用于处理节点数组.当然,还有其他示例,但是其中一个将成为您想要的递归函数,而另一个将成为循环,或者使您一次只对一件事情调用递归函数的事物.同样,还有其他情况.

If you have a tree where each root has an array of children, then you can write two functions to bounce back and forth between one another: one to deal with a node, one to deal with an array of nodes. There are other examples, of course, but one is going to be the recursive function you want, and the other is going to be a loop, or something that lets you call the recursive function on one thing at a time... usually; again, there are other cases.

const tree = {
  value: 1,
  children: [{
    value: 2,
    children: []
  }, {
    value: 3,
    children: []
  }]
};

const sumChildren = children =>
  children
    .map(sumNode)
    .reduce((x, y) => x + y, 0);

const sumNode = node =>
  node.value + sumChildren(node.children);

const total = sumNode(tree); // 6

承诺解决方案

就承诺而言,通常会错过的一件事是,您可以在 .then 内返回承诺,并使承诺的等待时间更长.解析后,它将具有b解析所用的值(或b所具有的错误)

One of the things that's usually missed, in terms of promises, is that you can return a promise, inside of a .then and cause the resolution of the promise to wait longer. When it resolves, it will have the value that b resolved with (or the error that b had)

eventuallyGetA()
  .then(a => eventuallyGetB(a.data))
  .then(b => console.log(`I waited for ${b}`));

您甚至可以做类似的事情

You can even do something like

const wait = ms =>
  new Promise(resolve => setTimeout(resolve, ms));

doX()
  .then(() => wait(2000))
  .then(doY)
  .then(() => wait(3000))
  .then(doZ);

关于该序列将要执行的操作应该非常简单.

It should be pretty straightforward as to what that sequence is going to do.

希望有帮助.

这篇关于递归承诺创建树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆