There is no simple, straight-forward way to make any code yield to the browser (or Node.js) event loop at any given point, but something you can do is
- make the function
async so it returns a promise and becomes interruptible
- strew it with
awaits to something that allows the event loop to do something else every now and then (and have the event loop itself resume your function); here that "something" is just a promisified setTimeout.
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function reverseString(str) {
let revString = '';
for (let i = str.length - 1; i >= 0; i--) {
revString += str[i];
console.log(`Reversing character ${i} of ${str}`);
await delay(0);
}
return revString;
}
reverseString('Hernekeitto').then(console.log);
reverseString('Viina').then(console.log);
reverseString('Teline').then(console.log);
reverseString('Johannes').then(console.log);
This will print out (e.g.)
Reversing character 10 of Hernekeitto
Reversing character 4 of Viina
Reversing character 5 of Teline
Reversing character 7 of Johannes
Reversing character 9 of Hernekeitto
Reversing character 3 of Viina
Reversing character 4 of Teline
Reversing character 6 of Johannes
Reversing character 8 of Hernekeitto
so you can see that all 4 calls are being done asynchronously.
Of course, this will also be potentially a lot slower than the synchronous, blocking code; you could make it yield every n items or every n milliseconds, for example...
setTimeout, orfetch. You can't write your own "asynchronous primitive" like these though.