re: Practical Ways to Write Better JavaScript VIEW POST

TOP OF THREAD FULL DISCUSSION
re: From the article: JS is single threaded, but not single-file (as in lines at school). Even though it isn't parallel, it's still concurrent. Sendi...
 

Your article writes that map is a construct that JS provides us that runs tasks in parallel.

But map doesn't care if you're passing it an async function or not—it runs a function on everything you pass it, in order. Notably, even this is possible, because async functions don't yield unless you actually call await:

const x = [1,2,3,4,5];

let expectedValue = 1;

x.map(async (value) => {
  if (value !== expectedValue) {
    console.info('actual', value, 'expected', expected);
  }
  expectedValue++;
});

At some level you're right that map isn't an inherently parallel construct. But I still stand by what I said, map has the potential of being parallelized on a level that a traditional for-loop does not. A for-loop explicitly surfaces a mechanism to enforce ordering, a map (and forEach) do not.

In your example, the code is not guaranteed to have a consistent result. The only way it could be consistent is if V8 guaranteed in-order execution of asynchronous tasks, which it does not.

Another differentiator in my mind is state. Anyone who has worked with distributed systems, knows that shared state is incredibly expensive. A traditional for-loop inherently provides shared state, the iterator/bounds check variable i. This inherently orders the loop, while map may be implemented as ordered, it's an implementation detail. Original MapReduce wasn't ordered.

I would say the moment you slap await in there, the code is no longer asynchronous. It's blocking as any other line.

That’s not true. If I await a web request in some random function, it will still be asynchronous as long as the random function is invoked asynchronously.

Try doing two awaits in a row and check if they run concurrently. This is the definition of synchronous.

code of conduct - report abuse