I'm figuring out how to prevent any blocking code from blocking the main event loop.
Suppose there's a function (let's assume it's going to block the event loop if implemented synchronously):
function reverseString(name){
let revString='';
for(let i=name.length;i>=0;i--){
revString+=name[i];
}
return revString;
}
If I use a callback and modify it to:
function reverseString(name, callback){
let revString='';
for(let i=name.length;i>=0;i--){
revString+=name[i];
}
callback(revString);
}
It's still a synchronous callback.
How do I convert the function into its asynchronous version using a callback?
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
async
so it returns a promise and becomes interruptibleawait
s 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...