Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nodejs async loop is blocking React UI render

I have an electron application where I need to send a lot of data through UDP. This process is started through a click of a button in my React UI, and this example simplifies my problem. My React button:

<button
  onClick={() => {
    foo();
  }}
>
  Run foo
</button>;

Foo function:

export const foo = async () => {
  while (true) {
    console.log("hello");
  }
};

While foo is asynchronous, it still freezes the React UI!

like image 941
asd12tgzxvbgt Avatar asked Dec 18 '25 10:12

asd12tgzxvbgt


1 Answers

An async function still blocks the main (and only) thread while it's being executed; async functions help usually because they call library functions that actually free up the main thread.

For instance, if instead of doing a simple infinite loop you did something like this:

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

function yieldThread() {
  return new Promise(resolve => resolve());
}

export const foo = async () => {
  while (true) {
    console.log("hello");
    await timeout(2000);
    //or
    await yieldThread();
  }
};

Your main thread wouldn't have been blocked.

Of course a timeout or a simple yield isn't usually the correct way to handle this situation, but it should exemplify the typical structure.

Assuming you have a function sendUdp(packet, callback) that has as first argument the packet you need to send and as second a callback without arguments when it has finished sending, you could do something like this:

export const foo = async () => {
  while (true) {
    const packet = getPacket();
    await new Promise(resolve => {
        sendUdp(packet, resolve);
    });
  }
};
like image 72
gcali Avatar answered Dec 21 '25 01:12

gcali