1

I have this object tree which is represented as follows (simplified):

var root = [
    { name: 'child1',
      data: 'other_data',
      children: [ {
         name: 'grand_child1',
         data: 'other_data',
         children: [...]
      }, ... ]
    },
    { name: 'child2',
      data: 'other_data',
      children: [ {
         name: 'grand_child2',
         data: 'other_data',
         children: [...]
       }, ... ]
    }
]

I need to loop through this object tree and instantiate objects based on the data provided in the children, but this process takes a few seconds and it freezes the browser in the mean time.

I need to have a timeout between iterations of my loop, to give the browser a chance to clear the event queue.

How would I go about this?

This is how I am currently looping through them, without the timeout. I am currently using a mutual recursion pattern.

function performSingleNodeComputation(node) {
  performHeavyComputation(node.data)
  if(node.children) {
    performMultipleNodeComputation(node.children);
  }
}

function performMultipleNodeComputation(nodes) {
  nodes.forEach(function (node) {
    performSingleNodeComputation(node);
  });
}

performMultipleNodeComputation(root);

To reiterate, I need a timeout between every invocation of performHeavyComputation

Luke
  • 5,567
  • 4
  • 37
  • 66
  • This post might give you some ideas http://stackoverflow.com/questions/758688/sleep-in-javascript-delay-between-actions – Lucien Stals Jul 31 '15 at 03:41

1 Answers1

1

2 easy solutions

1st approach: delay 1st level node computation like this

var root = [{ 
      name: 'child1',
      data: 'other_data0',
      children: [{
         name: 'grand_child1',
         data: 'other_data1',
         children: null
      }]
    }, {
      name: 'child2',
      data: 'other_data2',
      children: [{
         name: 'grand_child2',
         data: 'other_data3',
         children: null
      }]
    }
];


function performHeavyComputation(data){
  console.log(data);
}

function performSingleNodeComputation(node) {
  performHeavyComputation(node.data);
  if (node.children) {
    performMultipleNodeComputation(node.children);
  }
}

function performMultipleNodeComputation(nodes) {
  var i = 0;
  function inner() {
    performSingleNodeComputation(nodes[i]);
    ++i;
    if (i < nodes.length){
      setTimeout(inner, 1000);
    }
  }
  inner();
}

performMultipleNodeComputation(root);

2nd approach: compose array with nodes and perform heavy operations 1 by 1 with delay

var root = [{ 
      name: 'child1',
      data: 'other_data0',
      children: [{
         name: 'grand_child1',
         data: 'other_data1',
         children: null
      }]
    }, {
      name: 'child2',
      data: 'other_data2',
      children: [{
         name: 'grand_child2',
         data: 'other_data3',
         children: null
      }]
    }
];

function delayedProccessing (root) {

  var list = [];

  function delayComputation(data) {
    list.push(data);
  }

  function performSingleNodeComputation(node) {
    delayComputation(node.data);
    if (node.children) {
      composeList(node.children);
    }
  }

  function composeList(nodes) {
    for (var i = 0; i < nodes.length; ++i){
      performSingleNodeComputation(nodes[i]);
    }
  }

  function performHeavyComputation(data){
    console.log(data);
  }

  function proccessList() {
    var i = 0;
    function inner () {
      performHeavyComputation(list[i]);
      ++i;
      if (i <= list.length){
        setTimeout(inner, 1000);
      }
    }
    inner();
  }

  composeList(root);

  proccessList();
}

delayedProccessing(root);
Andrey
  • 4,020
  • 21
  • 35