Is the method [1, 2, 3].map(item=>f(item))
execute f(1), f(2), f(3)
parallelly? Or execute like "f(1), then f(2), then f(3)"?
Asked
Active
Viewed 1,149 times
2
-
2the second. At the moment there's no concurrency in Ecmascript. – Mario Vernari Jan 29 '21 at 02:41
-
@MarioVernari Not only "at the moment", but since it's inception and likely for the foreseeable future. The single-threaded nature of JavaScript is at the core of how you use the language. – Scott Marcus Jan 29 '21 at 02:53
-
@ScottMarcus Atomics and shared arrays are already a native part of the language (but of course, that has nothing to do with `map`, and how/whether one could even start a parallel process is left to the embedder of the language) – Bergi Jan 29 '21 at 03:01
1 Answers
-2
Actually it execute "f(1), then f(2), then f(3)"?
Because JS is single-threaded. So if the f
function is an async task (setTimeout, Ajax call, etc..
), then it can be scheduled
to waits
parallelly combined with promise.all
. Otherwise, it still has to execute synchronously.
One more thing to keep in mind is when you use await
inside async
function,
It does only waits parallel when you use promise.all
.
var tick;
const log = (v) => console.log(`${v} \n Elapsed: ${Date.now() - tick}`);
const f = (number) => new Promise(resolve => {
setTimeout(() => log(number), 1000);
});
async function Run(){
tick = Date.now();
await Promise.all([f(1), f(2), f(3)]);
}
function Run_2(){
tick = Date.now();
[f(1), f(2), f(3)];
}
Run();
Run_2();
While you await
each f
, it takes 3s in total.
var tick;
const log = (v) => console.log(`${v} \n Elapsed: ${Date.now() - tick}`);
const f = (number) => new Promise(resolve => {
setTimeout(() => resolve(number), 1000);
});
async function Run(){
tick = Date.now();
let a = await f(1);
let b = await f(2);
let c = await f(3);
log([a, b, c]);
}
Run();
However, Promise.all
can only waits async tasks in parallel. It can't convert a synchronous CPU block code into a separate thread or anything.

Nguyễn Văn Phong
- 13,506
- 17
- 39
- 56
-
@PONPON Does this answer your question? Let me know if you need any help. – Nguyễn Văn Phong Jan 29 '21 at 03:34
-
`Promise.all` neither causes parallel processing nor does it do any scheduling. And it has nothing to do with the question about `.map()`. – Bergi Jan 29 '21 at 03:36
-
Really? 2 examples above tell me that `Promise.all` make the async task run parallel, sir. – Nguyễn Văn Phong Jan 29 '21 at 03:37
-
-
It's the async task that runs in parallel not `Promise.all`. If you call blocking functions and pass them to `Promise.all` they will not be automatically converted to run in parallel. (Even so, `setTimeout()` cannot run anything in parallel due to javascript's single-threaded nature - it only **waits** in parallel) – slebetman Jan 29 '21 at 03:58
-
@Phong Drop the `Promise.all` call, write just `[f(1), f(2), f(3)]`, and the three timeouts will still happen concurrently. – Bergi Jan 29 '21 at 04:05
-
@slebetman You mean the same as me `However, Promise.all can only schedule async tasks in parallel. It can't convert a synchronous CPU block code into a separate thread or anything.` – Nguyễn Văn Phong Jan 29 '21 at 04:16
-
@Bergi I got what you mean. So when should I use `Promise.all` to get its feature? – Nguyễn Văn Phong Jan 29 '21 at 04:18
-
@Phong Then I don't think you've stated your understanding clearly in your answer. Your answer seem to imply that `Promise.all` makes the functions run in parallel. It does not. It only **waits** for parallel. You can prove this to yourself by removing `Promise.all` from your code and seeing that it still waits for the `setTimeout` in parallel even without passing it to `Promise.all` – slebetman Jan 29 '21 at 04:24
-
-
I've just updated my answer with your advice, pls kindly take a look at then give me your feedback if it's possible. Many thanks, both of you @slebetman & Bergi. – Nguyễn Văn Phong Jan 29 '21 at 05:14