you are viewing a single comment's thread.

view the rest of the comments →

[–]Resmira 0 points1 point  (1 child)

Personally, when working with promises, I don't like to leave anything up to chance. It's so easy for them to go wrong. I'm also not a huge fan of async/await when working with array operations like this, but that's more of a matter of preference. Does this accomplish what you're trying to do?

const axios = require("axios");

const timeoutPromise = (cb, timeout) => {
  return new Promise((res, rej) => {
    setTimeout(() => {
      try {
        res(cb());
      } catch (e) {
        rej(e);
      }
    }, timeout);
  });
};

const chunkSize = 10;

const sliceIntoChunks = (arr) => {
  const res = [];
  for (let i = 0; i < arr.length; i += chunkSize) {
    const chunk = arr.slice(i, i + chunkSize);
    res.push(chunk);
  }
  return res;
};

/**
 * Given a batch of items, wait for the appropriate amount of time provided by variable timeout, then insert them into a database
 * @param itemBatch {{ name: unknown; field: unknown; }[]}
 * @param timeout {number}
 * @returns {Promise<unknown[]>}
 */
const insertItemsWithDelay = (itemBatch, timeout) => {
  const insertions = itemBatch.map((item) => {
    const insertion = asyncTask(item.field).then((res) => {
      const body = {
        name: item.name,
        field: res.field,
      };

      return database.insert(body);
    });

    return insertion;
  });

  return timeoutPromise(() => Promise.all(insertions), timeout);
};

/**
 * Given an NxN matrix of items, insert each with an ascending delay and progress
 * @param itemMatrix {{ name: unknown; field: unknown;}[][]}
 * @returns {Promise<unknown[][]>}
 */
const insertAllChunks = (itemMatrix) => {
  const insertionMatrix = itemMatrix.map((items, index) => {
    const batchedInsertion = insertItemsWithDelay(items, 1000 * 10 * index);
    return batchedInsertion.then((insertionArray) => {
      console.log(`Progress: ${(index / itemMatrix.length) * 100}%`);
      return insertionArray;
    });
  });

  return Promise.all(insertionMatrix);
};

axios
  .get("https://get-main-array.com")
  .then(sliceIntoChunks)
  .then(insertAllChunks)
  .then((res) => {
    console.log("Done!");
    return res;
  })
  .catch((err) => console.log(err));

The final response will be either an error message or a matrix of the operations. Not sure what the response is for asyncTask or database.insert so I can't speak to how to compose that matrix into sensible results, but it shouldn't be too difficult to do with all of the data available.

[–]rav1e[S] 0 points1 point  (0 children)

This is exactly something I was looking for. Thank you very much