node.jscronnode-cronnode-schedule

how can i stop node-cron schedule in 'while-loop'


I want to get response for a specific url using node-cron.

As in the example code below, 'scheduler' requests to specific url every 10 seconds.

However, I want this action to be performed only 10 times.

(There may be other ways, but I definitely want to use the 'start' and 'stop' methods of node-crone.)

I really want to use the while statement.. The code I wrote doesn't wait for the response of the 'start' method, and as a result, an infinite loop is executed.

I'll leave the code I wrote below, so if you have a solution, please reply. thanks!!

import cron from 'node-cron';
import axios from 'axios';
import fsPromise from 'fs/promises';

let cronCnt = 0;
const cronSchedule = cron.schedule(
  '*/10 * * * * *,',
  async () => {
    try {
      const result = await axios.get(options);
      await fsPromise.writeFile(path, result.data, { encoding: 'utf-8' });
      cronCnt += 1;
    } catch (e) {
      console.error(e);
    }
  },
  {
    scheduled: false,
  },
);

(async () => {
  while (true) {
    if (cronCnt < 10) {
      await cronSchedule.start(); // i know.. 'cron.start()' doesnt'return promise... :(
    } else {
      await cronSchedule.stop(); // i know.. 'cron.stop()' doesnt'return promise... :(
      break;
    }
  }
})();


Solution

  • A couple things:

    1. Scheduling */10 * * * * *, results in an exception. You'll simply need to remove that last comma.

    2. Take a look at the node-cron code here in GitHub. More on this below.

    When calling start() in a loop, you are essentially scheduling work to be done, then clearing that work to be scheduled in the next call, as the first line in start() clears any previous timers.

    So, let's let node-cron do the scheduling 😃:

    (() => {
      cronSchedule.start()
    
      while (true) {
        if (cronCnt < 10) {
          // i would sleep here for a second or something
        } else {
          cronSchedule.stop();
          break;
        }
      }
    })();