You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.2 KiB
JavaScript

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 inner loop iteration
loop();
if (stopCondition()) {
// Resolve promise, exit outer loop, and do not re-enter
resolve();
break;
} else if (yieldCondition()) {
// Exit outer loop and queue up next outer loop iteration
// for next event cycle
setTimeout(outerLoop, 0);
break;
}
// Continue to next inner loop iteration without yielding
}
};
// Start the first iteration of outer loop, 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) {
let status = `Found ${primes.length} primes between 2 and ${n}`;
document.getElementById("display").textContent = status;
console.log(status);
}
}
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()) {
let status = `Found ${primes.length} primes between 2 and ${n}`;
document.getElementById("display").textContent = status;
console.log(status);
}
};
// Execute
doUntil(loop, stopCondition, yieldCondition);
}