5

I'm new to javascript and node.js,

Here I have two loops, I want to let them run in parallel,

function loop1(){
    for (var i = 10000; i < 20000; i++) {
        console.log(i);
    }
}
function loop2(){
    for (var i = 0; i < 10000; i++) {
        console.log(i);
    }
}
loop1();
loop2();

Which means the output I expected is like

10000
0
10001
1
...
19999
9999

But this outputs

10000
10001
...
19999
0
1
...
9999

I have tried using promises like

Promise.all([loop1(), loop2()])

But nothing happened.

Is there any idea about this? My final target is to split files in a folder's into half and process them in parallel. So Multi-Threading or Multi-Processing might be acceptable. Thanks for your help.

maxcsh
  • 53
  • 1
  • 5
  • Does this answer your question? [Can javascript run multiple functions at once?](https://stackoverflow.com/questions/44465787/can-javascript-run-multiple-functions-at-once) – Md Sabbir Alam Dec 15 '20 at 10:29
  • You'll get the desired result if you use `console.log(i); console.log(i - 10000);` instead, but I don't think that'll help here. I'm also not sure what you hope to gain by processing multiple files at the same time, even if JavaScript were suitable to do that. –  Dec 15 '20 at 10:30
  • 1
    I read this post and tried to use Promise.all([loop1(), loop2()]), but it did not work as I expected. It just run two loop separately. – maxcsh Dec 15 '20 at 10:33

5 Answers5

5

only async functions* runs async** (without workers)

async function loop1(){
    for (var i = 10000; i < 20000; i++) {
        await console.log(i);
    }
}
async function loop2(){
    for (var i = 0; i < 10000; i++) {
        await console.log(i);
    }
}
loop1();
loop2();

*async function : include those use event/timer/promise internally and (optionally) return Promise

** with await inside them

apple apple
  • 10,292
  • 2
  • 16
  • 36
3

Excellent question.

JS is single-threaded, which means it cannot run things in parallel. It might be weird for an asynchronous language like JS to run everything sequentially, but that is basically what happens.

JS however provides the illusion of working in parallel by splitting work into tasks and microtasks via the event loop. There's a lot to say about the event loop and I'd recomment this talk by Jake Archibald on the subject, but basically your function loop1 is synchronous and won't be split into tasks, therefore it will run into completion before doing anything else.

You won't be able to have loop1 and loop2 run in parallel, but you can split them into microtasks so that they'll execute like

t=0 loop1's microtask 1
t=1 loop2's microtask 1
t=2 loop1's microtask 2
t=3 loop2's microtask 2
...

A simple way to achieve this would be to await at each iteration. That'll create an asynchronous promise that resolves as soon as possible, and in the meantime give back the control flow to other awaiting tasks or microtasks.

That is why this runs loop1 then loop2

const loop1 = () => {
  for (let i = 0; i < 5; i++) {
    console.log(i);
  }
}
const loop2 = () => {
  for (let i = 5; i < 10; i++) {
    console.log(i);
  }
}
loop1();
loop2();

but this runs loop1 and loop2 "in parallel"

const loop1 = async () => {
  for (let i = 0; i < 5; i++) {
    console.log(i);
    
    // defer the remaining work to another microtask
    // gives back control to awaiting microtasks, like loop2's remaining work
    await null;
  }
}
const loop2 = async () => {
  for (let i = 5; i < 10; i++) {
    console.log(i);
    
    // defer the remaining work to another microtask
    // gives back control to awaiting microtasks, like loop1's remaining work
    await null;
  }
}
loop1();
loop2();
Nino Filiu
  • 16,660
  • 11
  • 54
  • 84
2

For parallel work, you can use Web Workers in javascript for browser and worker threads in node.js

Also, you can use setTimeout, but it will not execute in really parallel, in will only tell javascript to run latter:

function loop1(){
    for (let i = 100; i < 200; i++) {
        setTimeout(() => console.log(i));
    }
}
function loop2(){
    for (let i = 0; i < 100; i++) {
        setTimeout(() => console.log(i));
    }
}

loop1();
loop2();
Ricardo Rocha
  • 14,612
  • 20
  • 74
  • 130
1

Running parallel using promises.all()

function loop1(){
      return new  Promise((resolve, reject) =>{
        for (var i = 10000; i < 20000; i++) {
          console.log('loop1 =>', i);
        }
        resolve();
      })
    }
    
    function loop2(){
      return new Promise((resolve, reject) =>{
      for (var i = 0; i < 10000; i++) {
        console.log('loop2 =>', i);
      }
     
      resolve();
    });
    }
    
    Promise.all([loop1(), loop2()]);
Debasis Das
  • 549
  • 3
  • 8
0

Javascript Running in parallel using async.parallel()

https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/flow_control_using_async

Debasis Das
  • 549
  • 3
  • 8