当前位置: 代码迷 >> JavaScript >> 递归遍历一棵树,两次迭代之间都有超时
  详细解决方案

递归遍历一棵树,两次迭代之间都有超时

热度:48   发布时间:2023-06-05 11:50:50.0

我有这个对象树,表示如下(简化):

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

我需要遍历此对象树并根据子级中提供的数据实例化对象,但是此过程需要花费几秒钟的时间,同时冻结了浏览器。

我需要在循环的两次迭代之间设置超时,以便浏览器有机会清除事件队列。

我将如何处理?

这就是我目前在没有超时的情况下遍历它们的方式。 我目前正在使用相互递归模式。

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

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

performMultipleNodeComputation(root);

重申一下,我需要在每次调用performHeavyComputation之间设置一个超时时间

2个简单的解决方案

第一种方法:像这样延迟第一级节点的计算

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);

第二种方法:用节点组成数组并延迟执行一对一的繁重操作

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);
  相关解决方案