Home > Blockchain >  Asynchronous readline loop without async / await
Asynchronous readline loop without async / await

Time:03-25

I'd like to be using this function (which runs fine on my laptop), or something like it, on my embedded device. But two problems:

  1. Node.JS on our device is so old that the JavaScript doesn't support async / await. Given our hundreds of units in the field, updating is probably impractical.
  2. Even if that weren't a problem, we have another problem: the file may be tens of megabytes in size, not something that could fit in memory all at once. And this for-await loop will set thousands of asynchronous tasks into motion, more or less all at once.

async function sendOldData(pathname) {
    const reader = ReadLine.createInterface({
      input: fs.createReadStream(pathname), 
      crlfDelay: Infinity
     })
    for await (const line of reader) {
      record = JSON.parse(line);
      sendOldRecord(record);
    }
}

function sendOldRecord(record) {...}

Promises work in this old version. I'm sure there is a graceful syntax for doing this sequentially with Promises:

read one line
massage its data
send that data to our server

sequentially, but asynchronously, so that the JavaScript event loop is not blocked while the data is sent to the server.

Please, could someone suggest the right syntax for doing this in my outdated JavaScript?

CodePudding user response:

Make a queue so it takes the next one off the array

function foo() {

  const reader = [
    '{"foo": 1}',
    '{"foo": 2}',
    '{"foo": 3}',
    '{"foo": 4}',
    '{"foo": 5}',
  ];


  function doNext() {
    if (!reader.length) {
      console.log('done');
      return;
    }
    const line = reader.shift();
    const record = JSON.parse(line);
    sendOldRecord(record, doNext);
  }
  
  doNext();

}

function sendOldRecord(record, done) {
  console.log(record);
  // what ever your async task is
  window.setTimeout(function () {
    done();
  }, Math.floor(2000 * Math.random()));
}

foo();

CodePudding user response:

Basically you can achieve this using functional approach:

const arrayOfValues = [1,2,3,4,5];

const chainOfPromises = arrayOfValues.reduce((acc, item) => {

  return acc.then((result) => {
    // Here you can add your logic for parsing/sending request
    
    // And here you are chaining next promise request
    return yourAsyncFunction(item);
  })

}, Promise.resolve());

// Basically this will do
// Promise.resolve().then(_ => yourAsyncFunction(1)).then(_ => yourAsyncFunction(2)) and so on...

// Start
chainOfPromises.then();
  • Related