递归循环遍历树,在迭代之间设置超时
Recursively loop through a tree with a timeout in between iterations
我有这个对象树,表示如下(简化):
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);
第二种方法:将数组与节点组合在一起,并通过延迟执行 1 对 1 的繁重操作
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);
我有这个对象树,表示如下(简化):
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);
第二种方法:将数组与节点组合在一起,并通过延迟执行 1 对 1 的繁重操作
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);