skip to Main Content

I have function fetchData that accepts an integer id and calls promise with random resolve time

  const promise = (ms) => new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('Done!');
      }, ms);
    });

    const fetchData= async (id) => {
      const ms = Math.floor(Math.random() * 1000);
      const ans = await promise(ms);
      return ans
    }

I have an array of ids = [1, 2, 3, 4, 5] I need to call the fetchData with all ids in parallel and reorder the ids array based on the time taken to resolve

I tried this

const main = async () => {
  const ids = [1, 2, 3, 4, 5];
  const promises = ids.map(id => fetchData(id));
  const result = await Promise.all(promises);
  console.log(result)
}

but it doesn’t show which one resolved first

I added this to make it more clear
Note: I don’t have access to edit fetchData function and the promises only return "Done". I can only edit the main function

4

Answers


  1. You need to return 2 parameters from your function,
    One will be the real answers and the second will be the time it took.

    To measure the time, you can use performance.now native call.

    When you have results of this 2 tuples you can sort them be processed time.

    Login or Signup to reply.
  2. I did it just for fun:

      const promise = (ms) => new Promise((resolve, reject) => {
          setTimeout(() => {
              resolve('Done!');
          }, ms);
      });
    
      const fetchData = async (id, callback = () => {}) => {
          const ms = Math.floor(Math.random() * 1000);
          const ans = await promise(ms);
          callback(id);
          return ans
      }
    
      const ids = [1, 2, 3, 4, 5];
      const idsInOrder = [];
      const callback = id => idsInOrder.push(id);
    
      const promises = ids.map(id => fetchData(id, callback));
    
      Promise.all(promises)
          .then(function() {
              console.log('ids in order:');
              console.log(idsInOrder);
          })
    

    I added a callback function to fetchData so it could record the order that the promises return in.

    Login or Signup to reply.
  3. Here’s how you might do it from main function. I assume you’re interested in the processing times only, but it can be easily extended to return the actual fetched data as well.

    const promise = (ms) => new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('Done!');
      }, ms);
    });
    
    const fetchData = async(id) => {
      const ms = Math.floor(Math.random() * 1000);
      const ans = await promise(ms);
      return ans;
    }
    
    
    const main = async() => {
      const ids = [1, 2, 3, 4, 5];
      const promises = ids.map(async(id) => {
        const t0 = performance.now();
        await fetchData(id);
        return performance.now() - t0;
      });
      const result = await Promise.all(promises);
      const ids_sorted = ids.sort((a, b) => result[a - 1] - result[b - 1]);
      console.log(JSON.stringify(result)); // JSON.stringify is here for readability
      console.log(JSON.stringify(ids_sorted));
    }
    
    main()
    .as-console-wrapper {max-height:100% !important; top:0}
    Login or Signup to reply.
  4. It’s done in 1 line without changing anything else:

    const result = [];
    await Promise.all(ids.map(id => fetchData(id).then(done => result.push(done))));
    
      const promise = (ms) => new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(`resolved in ${ms}ms!`);
          }, ms);
        });
    
        const fetchData= async (id) => {
          const ms = Math.floor(Math.random() * 1000);
          const ans = await promise(ms);
          return ans
        }
        
    const ids = [1,2,3,4,5];
    
    (async() => {
    
      const result = [];
      await Promise.all(ids.map(id => fetchData(id).then(done => result.push(done))));
      console.log(result);
    
    })();
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search