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.
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.
Share Improve this question asked Dec 15, 2020 at 10:24 maxcshmaxcsh 631 silver badge5 bronze badges 3- Does this answer your question? Can javascript run multiple functions at once? – Md Sabbir Alam Commented Dec 15, 2020 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. – user5734311 Commented Dec 15, 2020 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 Commented Dec 15, 2020 at 10:33
6 Answers
Reset to default 5only 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
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 rement 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 pletion 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();
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();
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()]);
Javascript Running in parallel using
async.parallel()
https://developer.mozilla/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/flow_control_using_async
To run 2 loops simultaneously using 2 CPU threads on Node.js you should use Worker threads
. To handle them easily I prefer to use some ready-made library, for example workerpool.
Here is an example:
Heavy loops
function loop1() {
let res = 0;
for (var i = 10000000000; i < 20000000000; i++) {
res = res + i;
}
return res;
}
function loop2() {
let res = 0;
for (var i = 0; i < 10000000000; i++) {
res = res + i;
}
return res;
}
Run them using 1 thread - it's slow
//this code will run on 1 CPU core
//first loop1
const result1 = loop1();
console.log("result1:", result1); //result1: 149999999990002750000
//and then loop2
const result2 = loop2();
console.log("result2:", result2); //result2: 49999999990067860000
Run then using 2 threads - 2 times faster
import workerpool from "workerpool";
const pool = workerpool.pool();
//...loop1 and loop2 function definitions...
//this code will run using 2 CPU cores simultaneously
//loop1 on one core
pool.exec(loop1, [])
.then(function (result) {
console.log("result1:", result); //result1: 149999999990002750000
})
.catch(function (err) {
console.error(err);
})
.then(function () {
pool.terminate(); // terminate all workers when done
});
//and loop2 on another core
pool.exec(loop2, [])
.then(function (result) {
console.log("result2: ", result); //result2: 49999999990067860000
})
.catch(function (err) {
console.error(err);
})
.then(function () {
pool.terminate(); // terminate all workers when done
});