1

I have a simple loop. I am just trying to find out what are different ways I can write my code so I can turn a blocking code into no blocking.

function jsSum(){
    let a = 3.14, b = 4.16;
    for(i = 0; i < 10000000000; i++){
        a += b;
    }
    let total = a;
    return total;
}

Is there any way I can run it little faster or In event loop?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
xMayank
  • 1,875
  • 2
  • 5
  • 19
  • What problem are you really trying to solve here? The code doesn't have a stated objective such that we could suggest more efficient ways to create the output. It's blocking code (no asynchronous operations involved) so it blocks the event loop while running. The only ways to make something like this not block the event loop would be to run it in a [Worker Thread](https://nodejs.org/api/worker_threads.html), run it in another process or to write it in native code where you could use a native thread and make it asynchronous. – jfriend00 Mar 29 '20 at 22:34

1 Answers1

2

You only have one thread to work with in the main event loop, so there's no way to have long CPU intensive tasks that don't block if they run in that thread. Node allows various ways of spawning threads and processes. Here's one way to take the loop and put it into a new thread.

const { Worker, isMainThread, parentPort, workerData} = require('worker_threads');

  if (isMainThread) {

    function doAsyncThing(n) {
      return new Promise(resolve => {
        const worker = new Worker(__filename, {workerData: {n}});
        worker.on('message', resolve);
      });
    };

    // run two loops in parallel:
    doAsyncThing(1)
    .then(res => console.log("got response from thread1:", res))

    doAsyncThing(2)
    .then(res => console.log("got response from thread2:", res))


  } else {
    const {n} = workerData;
    let res = jsSum(n)
    parentPort.postMessage(res);
  }


function jsSum(n){
    console.log("jsSume started for call ", n)
    let a = 0;
    for(let i = 0; i < 100; i++){
        console.log(`worker ${n} in loop ${i}`)
        a += 1;
    }
    let total = a;
    return total;
}

If you watch the logs you will see the loops running together in parallel like:

worker 1 in loop 1
worker 1 in loop 2
worker 1 in loop 3
worker 1 in loop 4
worker 2 in loop 1
worker 2 in loop 2
worker 1 in loop 5

After the calls to doAsyncThing() your main thread is free for other things like responding to requests. Also (fwiw) console.log() is not a great tool for demonstrating this since the logs are sent to the main thread.

Mark
  • 90,562
  • 7
  • 108
  • 148