作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我需要访问树中的每个节点,做一些异步工作,然后找出所有异步工作何时完成。以下是步骤。
更新:
我最终使用了一种看起来像监视器/锁(但不是)的模式,让每个节点知道何时开始第 2 步。我使用事件和属性来跟踪节点的所有后代以了解何时开始开始第 3 步。
它有效,但人就是这么难读!有没有更清晰的模式?
function step1(el) { // recursive
var allDone = false;
var monitor = new Monitor();
var lock = monitor.lock(); // obtain a lock
$(el).attr("step1", ""); // step1 in progress for this node
// fires each time a descendant node finishes step 1
$(el).on("step1done", function (event) {
if (allDone) return;
var step1Descendants = $(el).find("[step1]");
if (step1Descendants.length === 0) {
// step 1 done for all descendants (so step 2 is complete)
step3(el); // not async
allDone = true;
}
});
// fires first time all locks are unlocked
monitor.addEventListener("done", function () {
$(el).removeAttr("step1"); // done with step 1
step2(el); // might have async work
$(el).trigger("step1done");
});
doAsyncWork(el, monitor); // pass monitor to lock/unlock
lock.unlock(); // immediately checks if no other locks outstanding
};
function step2(el) { // visit children
$(el).children().each(function (i, child) {
step1(child);
});
};
最佳答案
这是一个更新版本,它遍历节点树,处理初始根节点中的每个子节点,然后递归下降到每个子节点的树并处理它的子节点等等。
// Pass the root node, and the callback to invoke
// when the entire tree has been processed
function processTree(rootNode, callback) {
var i, l, pending;
// If there are no child nodes, just invoke the callback
// and return immediately
if( (pending = rootNode.childNodes.length) === 0 ) {
callback();
return;
}
// Create a function to call, when something completes
function done() {
--pending || callback();
}
// For each child node
for( i = 0, l = rootNode.childNodes.length ; i < l ; i++ ) {
// Wrap the following to avoid the good ol'
// index-closure-loop issue. Pass the function
// a child node
(function (node) {
// Process the child node asynchronously.
// I'm assuming the function takes a callback argument
// it'll invoke when it's done.
processChildNodeAsync(node, function () {
// When the processing is done, descend into
// the child's tree (recurse)
processTree(node, done);
});
}(rootNode.childNodes[i]));
}
}
这是一个您可能可以使用的基本示例...尽管没有您的问题的具体细节,它是半伪代码
function doAsyncTreeStuff(rootNode, callback) {
var pending = 0;
// Callback to handle completed DOM node processes
// When pending is zero, the callback will be invoked
function done() {
--pending || callback();
}
// Recurse down through the tree, processing each node
function doAsyncThingsToNode(node) {
pending++;
// I'm assuming the async function takes some sort of
// callback it'll invoke when it's finished.
// Here, we pass it the `done` function
asyncFunction(node, done);
// Recursively process child nodes
for( var i = 0 ; i < node.children.length ; i++ ) {
doAsyncThingsToNode(node.children[i]);
}
}
// Start the process
doAsyncThingsToNode(rootNode);
}
关于javascript - 清理模式来管理树上的多步异步进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9009622/
我是一名优秀的程序员,十分优秀!