Skip to content

Instantly share code, notes, and snippets.

@leihuang23
Created July 31, 2020 10:20
Show Gist options
  • Save leihuang23/1c620a8cd8291e4e7635f68c24f0cabc to your computer and use it in GitHub Desktop.
Save leihuang23/1c620a8cd8291e4e7635f68c24f0cabc to your computer and use it in GitHub Desktop.
Parsing and processing DOM nodes in a non-blocking way using CPS technique.
function traverse(node, processTask, continuation) {
processTask(node, function handleChildren() {
const children = node.childNodes;
function handleOne(i, len, continuation) {
if (i < len) {
traverse(children[i], processTask, function handleNext() {
handleOne(i + 1, len, continuation);
});
} else {
continuation();
}
}
handleOne(0, children.length, continuation);
});
}
const stats = {};
function histogram(node, continuation) {
if (node.nodeType === 3) {
node.nodeValue.replace(/\w+/g, function (match) {
stats[match] = stats[match] ? stats[match] + 1 : 1;
return match;
});
}
if (histogram.skip++ % 400 === 0) {
setTimeout(continuation, 0);
} else {
continuation();
}
}
histogram.skip = 0;
function show(continuation) {
function handleOne(i, keys, continuation) {
if (i < keys.length) {
const key = keys[i];
console.log(`${key}: ${stats[key]}`);
if (i % 20 === 0) {
setTimeout(function () {
handleOne(i + 1, keys, continuation);
}, 0);
} else {
handleOne(i + 1, keys, continuation);
}
} else {
continuation();
}
}
handleOne(0, Object.keys(stats), continuation);
}
function end() {
console.log('done');
}
traverse(document.body, histogram, function () {
show(end);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment