Search code examples
javascriptpromiseasync-awaites6-promiseasynccallback

Async programing in Javascript - Promise.all() do not work as expected


I'm stuck in Async programming in Javascript. I know that Promise.all() will run parallel.

Could you pls tell me what I'm wrong with this code below?

It should take 100ms. But actually, it takes 200ms :(

// 1. Define function here
var getFruit = async (name) => {
  const fruits = {
    pineapple: ":pineapple:",
    peach: ":peach:",
    strawberry: ":strawberry:"
  };
  await fetch('https://jsonplaceholder.typicode.com/photos'); // abount 100ms 
  return fruits[name];
};

var makeSmoothie = async () => {
  const a = getFruit('pineapple');
  const b = getFruit('strawberry');
  const smoothie = await Promise.all([a, b]);
  return smoothie;
  //return [a, b];
};
  
/// 2. Execute code here
var tick = Date.now();
var log = (v) => console.log(`${v} \n Elapsed: ${Date.now() - tick}`);
makeSmoothie().then(log);


Solution

  • Your logic is fine, it is running as parallel as possible from client side.

    You can test this by waiting on setTimeout instead of the fetch:

    await new Promise(resolve => setTimeout(resolve, 100));
    

    It's possible the placeholder site is queuing connections on its side or something. Either way you should measure with something predictable, not network.

    Edit:

    Just to explain a bit more that won't fit in a comment.

    Let's put my waiting trick into an actual function:

    const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
    

    OK, now you would call this as await wait(100). Now to compare:

    • await wait(100)
    • await fetch(...)

    In terms of your code setup, they are the same. They are perform some async task that takes around 100ms and returns. If Promise.all() were not running this in parallel, the wait(100) version would certainly take 200ms or longer.

    fetch is not as reliable of a test as setTimeout because it is running over the network. There's a lot of things you can't control with this call, like:

    • Some browsers limit how many parallel connections are made to the same domain
    • Lag in DNS or the server itself, typical network hiccups
    • The domain itself might force 1 connection at a time from your IP

    It's not clear exactly what is causing the apparent synchronous behavior here. Maybe you will find some answers in the network panel. But in terms of code, there is nothing else for you to do. It is provably parallelized with the setTimeout test, which is much more reliable as a test since it is just a local timer.