Skip to content Skip to sidebar Skip to footer

Recursive Promises To Create Tree

A tree api returns childrens when node element is passed to it. I pass the root node first and then on the basis of the nodes returned I pass all of them back recursively, if they

Solution 1:

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.

EDIT

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: []
  }]
};

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

constsumNode = node =>
  node.value + sumChildren(node.children);

const total = sumNode(tree); // 6

Promise Resolution

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

constwait = ms =>
  newPromise(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.

Hope that helps.

Post a Comment for "Recursive Promises To Create Tree"