Search code examples
javascriptnode.jsparallel-processingbatch-processingasync.js

async parallelLimit runs limit times only once


I am trying to make use of async.parallelLimit to update records in my db. I need to do this in a batches of 10 and each time the total records will be 1000. I am trying to understand how can i make use of this asyn.parallelLimit in my code. I looked at some example interpreation and tried but it is running only 10 times and after giving back 10 responses it does not give me next ones. I am trying to query the db by executing the filter and then sending the records into async.parallelLimit and get response of all those records. For now i am just trying to understand the parallelLimit and its working. Here is my code

const async = require("async");

module.exports = async (server) => {
  async function data(server) {
    return await resolveData(server);
  }

  function resolveData(server) {
    return new Promise((resolve) => {
      let parcel = server.models["Parcel"].find({
        order: "createdAt ASC",
        include: [
          {
            relation: "parcelStatuses",
          },
          {
            relation: "customerData",
            scope: {
              fields: ["firstName", "lastName", "cityId", "customerId"],
            },
          },
        ],
        limit: 1000,
        skip: 200,
      });
      resolve(parcel);
    });
  }
  // console.log(await data(server));
  var parcelData = await data(server);

  for (var i = 1; i <= parcelData.length; i++) {
    parcelData[i - 1] = (function (i) {
      return function () {
        console.log(i);
      };
    })(parcelData[i]);
  }

  async.parallelLimit(parcelData, 10, function (err, results) {
    if (results) {
      console.log("This is resilt", results);
    } else {
      console.log(err);
    }
  });
};

I need my parallelLimit function to just return me the records that my query fetch. I will run the update commands later. Since its returning me only 10 records i want to know what i am doing wrong


Solution

  • I'm not sure what the for loop is supposed to do. I'm guessing you're trying to create functions for each elements of the parcelData. An easy way to do that is just map over the parcelData and return an async function:

    let async = require("async");
    
    // Your data is here but I used a dummy array with 100 elements
    let parcelData = Array(100).fill(0).map((_, i) => i);
    
    // Just a dummy function to wait
    function delay(ms) {
        return new Promise(r => setTimeout(r, ms));
    }
    
    // map over array and return an `async` function;
    let tasks = parcelData.map(p => {
      return async () => {
        await delay(1000);
        console.log(p);
      }
    });
    
    // Finally execute the tasks
    async.parallelLimit(tasks, 10, (err, result) => {
        if (err) console.error('error: ', err)
        else console.log('done');
    });
    

    You can run the code on repl.it to see it in action. Here's one I made.