Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

fetch in parallel async/await with Promises.all

I continue to struggle with serial/parallel processing in JS (promises). I want to query my server and identify those queries that take longer than, say 500 ms. The following works, but as far as I understand, the queries are made one after another.

const query = async (queries) => {
    for (let i = 0, j = queries.length; i < j; i++) {
        let t = process.hrtime();
        const response = await fetch(queries[i]);
        const result = await response.json();
        t = process.hrtime(t);
        
        const ms = Math.round((t[0] * 1000) + (t[1] / 1000000));
        if (ms > 500) {
            console.log(ms, queries[i]);
        }
    }
}

query(arrayOfQueries);

// console output below (snipped for brevity)
3085 http://localhost:3010/v3/…
2463 http://localhost:3010/v3/…
2484 http://localhost:3010/v3/…
…

I change the above code to fire the queries in parallel, but now I get back an array of promises. I can’t figure out how to identify only those promises that take longer than 500ms to resolve

const query = async (queries) => {
    const r = await Promise.all(queries.map(async (q) => fetch(q)));
    console.log(r);
};

// console output
[
  Response {
    size: 0,
    timeout: 0,
    [Symbol(Body internals)]: { body: [PassThrough], disturbed: false, error: null },
    [Symbol(Response internals)]: {
      url: 'http://localhost:3010/v3/…',
      status: 200,
      statusText: 'OK',
      headers: [Headers],
      counter: 0
    }
  },
  Response {
    size: 0,
    timeout: 0,
    [Symbol(Body internals)]: { body: [PassThrough], disturbed: false, error: null },
    [Symbol(Response internals)]: {
      url: 'http://localhost:3010/v3/…',
      status: 200,
      statusText: 'OK',
      headers: [Headers],
      counter: 0
    }
  },
  Response {
    size: 0,
    timeout: 0,
    [Symbol(Body internals)]: { body: [PassThrough], disturbed: false, error: null },
    [Symbol(Response internals)]: {
      url: 'http://localhost:3010/v3/…',
      status: 200,
      statusText: 'OK',
      headers: [Headers],
      counter: 0
    }
  },

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

When running the queries in parallel, you would have to add code (similar to what you had for your non-parallel example) to time each one separately so you could track each individual request separately.

The time of each request overlaps so you can’t keep track of the timing of each individual request from the outside. Here’s an example of timing each individual request:

const query = async (queries) => {
    const r = await Promise.all(queries.map(async (q) => {
        const start = Date.now();
        const response = await fetch(q);
        const json = await response.json();
        const delta = Date.now() - start;
        console.log(`${delta}ms for ${q}`);
        return json;
    });
    return r;
};

This will output the timing for each request at the time it finishes which may not be in the same order that the requests were made. If you want, you can collect these timing results into an array and output all the timing at once at the end.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading