如何在异步递归方法完全就绪时创建回调
How to create a callback when an ansynchronous recursive method is completely ready
我需要一个递归函数与一个在递归完全完成后发生的回调异步发生。我简化了它,去掉了不相关的部分(这里是jsfiddle中的代码。
tree = {
"a": {
"b": 1,
"c": 2
},
"d": {
"e": {
"f": {
"g": 3
},
"h": 4,
"i": 5
},
"j": {
"k": 6,
"l": 7
},
"m": 8,
"n": 9
},
"o": {
"p": 10
},
"q": 11
};
Watcher = function() { };
Watcher.prototype.startDoingAsyncStuff = function(node, callback) {
var me = this,
key;
if(typeof node === "number") {
console.log(node);
} else {
for(key in node) {
if(node.hasOwnProperty(key)) {
(function(node) {
setTimeout(function() {
me.startDoingAsyncStuff(node, callback);
}, 500);
}(node[key]));
}
}
}
};
w = new Watcher();
w.startDoingAsyncStuff(tree, function() {
console.log("callback 1");
});
w.startDoingAsyncStuff(tree["d"], function() {
console.log("callback 2");
});
我需要在递归完成后执行提供给Watcher.startDoingAsyncStuff
的回调,但我不确定如何实现这一点。
这里的复杂因素是使用简单的计数器是不可能的,因为Watcher.startDoingAsyncStuff
应该能够在不等待先前调用完成的情况下执行多次。
基本上,对于子材料,你想要提供一个回调,它只是通知它上面的级别它已经完成了。在更高的级别,你有一个"完成"消息的计数,你期望接收,一旦你得到这个数字,你调用"真实"回调。
我最初有一个计数器原型,它可以在函数之外完成此操作,但实际功能非常简单,因此我将其合并到函数本身中。
Watcher.prototype.startDoingAsyncStuff = function(node, callback) {
var me = this,
key,
jobCount = 0;
if (typeof node === "number") {
console.log(node);
// There's no sub-stuff to do, so we're done here
callback();
} else {
for (key in node) {
if (node.hasOwnProperty(key)) {
(function(node) {
++jobCount;
setTimeout(function() {
// we create a sub-callback to decrement the counter
// and run the "real" callback when the counter is back
// to 0.
// This works as many times as needed, because jobCount
// is local and accessed via closure.
me.startDoingAsyncStuff(node, function() {
if (--jobCount == 0) callback();
});
}, 500);
}(node[key]));
}
}
}
};
在不添加额外超时的情况下,一种方法是在不实际执行任何主要任务的情况下对树进行第一次遍历,而是计算遍历的次数。假设你的树不是很大,你应该能够在不锁定浏览器的情况下同步完成这个操作。
然后执行第二次传递,并在执行每个主异步任务后增加另一个计数器;当它匹配第一次传递的计数时,您可以触发回调。
相关文章:
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- 为effect Composer创建GodRays效果过程
- 从javascript创建一个列表
- onkeyup无法动态创建多个文本区域
- 如何使用javascript从主svg对象动态创建svg视图框
- 如何访问声音管理器2创建的声音对象
- 我已经创建了一个jquery转盘,并使用if条件来运行和停止转盘
- Kendo:我该如何在树视图中创建一个递归的hieiarchy
- 使用Facebook live API创建实时视频对象时的隐私设置
- 在动态创建的元素上获取对特定选择器的引用
- 如何创建带有插槽的vue js组件预加载程序
- 如何在创建键时引用来自同一对象的键
- 如何创建JSON数组
- 从html创建一个指令,该指令按类名应用函数
- 使用Javascript创建测验页面
- 更改使用Chart.js创建的图表中的轴线颜色
- JavaScript名称空间和对象创建
- 动态创建的用户控件中的就绪函数
- 如何在异步递归方法完全就绪时创建回调
- 创建自定义打印就绪图像