Normally with a language that supports multithreaded processing you would just run the process in a background thread. What can we do in Javascript where we only have one thread?
The Magic
There is a concept in threading called Yield that halts the current thread and allows another threads to run. We could do the same thing by turning what is normally a loop with a Thread.Yield call into tail recursion using setTimeout.
The Novelty
var processWithYield = function(total, chunkSize, processData, onComplete) {
var processNextChunk = function(begin) {
if (begin < total) {
var end = begin + chunkSize;
if (end > total) {
end = total;
}
console.log("begin "+begin+", end "+end);
processData(begin, end);
console.log("Done processing, now we are setting next timeout beginning at "+end);
// Yield the thread by processing the next chunk in 100 milliseconds instead of right away.
setTimeout(function() {
processNextChunk(end);
}, 100);
} else {
console.log("All processing completed");
onComplete();
}
};
processNextChunk(0);
};
Variability
I would tweak the timeout length and the chunkSize until I had the desired data processing time vs. UI responsiveness ratio I wanted.
Further Research
Rather than using a chunkSize and a timeout length the time could be used to determine when a yield should be done. The time could be checked each iteration, then the processData function would only take one row at a time. If checking the time itself was costly in terms of CPU it could only be done once every 2 or more iterations depending on the time it takes to perform one iteration.
No comments:
Post a Comment