javascriptasynchronous-javascript

Prevent code from blocking the event loop


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?


Solution

  • 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

    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...