Initial commit.
commit
e1784d3a13
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>doUntil example</title></head>
|
||||
<body style="text-align:center">
|
||||
<div id="display">Press one of the buttons below</div>
|
||||
<p>
|
||||
<button onclick="findPrimesBlocking()">Find Primes (Blocking)</button>
|
||||
<button onclick="findPrimesNonBlocking()">Find Primes (Non-Blocking)</button>
|
||||
</p>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,91 @@
|
||||
function doUntil(loop, stopCondition, yieldCondition) {
|
||||
|
||||
// Wrap function in promise so it can run asynchronously
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
// Build outerLoop function to pass to setTimeout
|
||||
let outerLoop = function () {
|
||||
while (true) {
|
||||
|
||||
// Execute a single loop
|
||||
loop();
|
||||
|
||||
if (stopCondition()) {
|
||||
// Resolve promise, exit outer loop, and do not re-enter
|
||||
resolve();
|
||||
break;
|
||||
} else if (yieldCondition()) {
|
||||
// Exit loop and queue up more iterations
|
||||
// for next event cycle
|
||||
setTimeout(outerLoop, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
// Continue to next loop without yielding
|
||||
}
|
||||
};
|
||||
|
||||
// Start the first iteration, unless the stop condition is met
|
||||
if (!stopCondition()) {
|
||||
setTimeout(outerLoop, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check whether n is prime, given a list of all primes < n
|
||||
function isPrime(n, primes) {
|
||||
for (const p of primes) {
|
||||
if (n % p == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function findPrimesBlocking() {
|
||||
let primes = [];
|
||||
|
||||
for (let n = 2; n < 1000000; n++) {
|
||||
if (isPrime(n, primes)) {
|
||||
primes.push(n);
|
||||
}
|
||||
if (n % 10000 == 0) {
|
||||
document.getElementById("display").textContent =
|
||||
`Found ${primes.length} primes between 2 and ${n}`;
|
||||
}
|
||||
}
|
||||
document.getElementById("display").textContent =
|
||||
`Found ${primes.length} primes between 2 and 1000000`;
|
||||
}
|
||||
|
||||
function findPrimesNonBlocking() {
|
||||
|
||||
// Initialize loop variable and list of primes
|
||||
let n = 2;
|
||||
let primes = [];
|
||||
|
||||
// Yield every 1000 iterations and stop after 1000000
|
||||
const stopCondition = () => n == 1000000;
|
||||
const yieldCondition = () => n % 10000 == 0;
|
||||
|
||||
// Build the loop body to be passed to doUntil()
|
||||
const loop = () => {
|
||||
|
||||
// Determine if n is prime
|
||||
if (isPrime(n, primes)) {
|
||||
primes.push(n);
|
||||
}
|
||||
|
||||
// Increment n
|
||||
n += 1;
|
||||
|
||||
// Update DOM if we're about to yield
|
||||
if (yieldCondition()) {
|
||||
document.getElementById("display").textContent =
|
||||
`Found ${primes.length} primes between 2 and ${n}`;
|
||||
}
|
||||
};
|
||||
|
||||
// Execute
|
||||
doUntil(loop, stopCondition, yieldCondition);
|
||||
}
|
Loading…
Reference in New Issue