Schedule an async function in NodeJS
Asked Answered
S

4

8

I want to schedule a function which is asynchronous (async/await ruturn type) to run for every two minutes.

I tried with generic setInterval, node modules like node-schedule , cron, node-cron, async-poll but unable to achieve polling for a async function call.

This is what I tried in code:

cron.schedule("*/2 * * * *", await this.servicesManager.startPoll() => {
               console.log('running on every two minutes');
}); // this is not working breaks after first run
            
const job = schedule.scheduleJob(" */1 * * * *", async function() {
   try {
         return await this.ServicesManager.startPoll(); // this function startPoll is undefined when using this 
       } catch (e) {
         console.log(e);
   }
   console.log('Run on every minute');
});
                    
const event = schedule.scheduleJob("*/2 * * * *", this.ServicesManager.startPoll()); //using node-schedule , breaks after first time
cron.schedule("*/2 * * * *", await this.ServicesManager.startPoll()); // using cron same result as using node-schedule
return await this.ServicesManager.startPoll(); // without polling works
Simplicity answered 21/10, 2019 at 11:17 Comment(0)
R
10

Try something like this

// version 1
cron.schedule("*/2 * * * *", this.servicesManager.startPoll);

// version 2 => if servicesManager needs its `this` reference
cron.schedule("*/2 * * * *", async () => this.servicesManager.startPoll());

//version 3 ==> using node-schedule
schedule.scheduleJob("*/1 * * * *", async () => this.ServicesManager.startPoll());

I don't know about your servicesManager, you might have to use "version 2" from above to get it to work.

The schedule libraries need a function to execute, but instead they get a resolved Promise in the examples above.

Rimose answered 21/10, 2019 at 11:42 Comment(2)
This is part of nodejs based rest api server code , The ServicesManager is the wrapper around fucntional calls , the controller makes the calls from ServiceManager, version 1 and 2 is not working , similar way i am trying with schedule.scheduleJob("*/1 * * * *", async () => { this.ServicesManager.startPoll(); }); Here , ServicesManager calls startPoll which calls another async function and startPoll itself retruns asyncSimplicity
None of the code lines in the answer are syntactically correct.Venery
W
4

Scheduled asynchronous calls won't work using node-cron at least up to v3.0.0, but we can use node-schedule for this as follows.

JS

schedule.scheduleJob("*/1 * * * *", async () => await this.lifeService.addLife(userId, 1));

TS

import nodeSchedule = require("node-schedule");

const job: nodeSchedule.Job = nodeSchedule.scheduleJob('*/10 * * * * *', async () => {
    const life = await this.lifeService.getLives(userId);
    console.log(`user's life`, life);
});

Willow answered 24/1, 2022 at 18:17 Comment(0)
N
0

In my case i was using async/await function like :

myService.ts :

    @Cron(CronExpression.EVERY_10_SECONDS)
  async myExample() {
    const todaysDate: dayjs.Dayjs = dayjs();
    Logger.log(`Cron started at ${todaysDate}`);
    const users = await this.myRepo.getUsers();
   // code here
  }

myRepo.ts :

    getUsers() {
    return this.myModel.find({});
  }

but it was not working so changed myService.ts and tried then :

    @Cron(CronExpression.EVERY_10_SECONDS)
  async myExample() {
    const todaysDate: dayjs.Dayjs = dayjs();
    Logger.log(`Cron started at ${todaysDate}`);
    this.myRepo.getUsers().then(users => {
      // code here
    });
  }
Neomaneomah answered 17/6, 2021 at 8:23 Comment(0)
S
0

The answer from https://mcmap.net/q/1019518/-schedule-an-async-function-in-nodejs already shows in Version 1 and 2 that is it possible with node-cron (at least with version v3+).

Here are some minimal working examples (with "require" syntax) that show better, how to handle async functions with node-cron. Each scheduled cron job logs "start" every second and "finished" 300ms after that.

const cron = require('node-cron')
const log = console.log.bind(this)

const wait = ms => new Promise(r => setTimeout(r, ms))

// Version with async function
cron.schedule('* * * * * *', async () => {
  log('start')
  await wait(300)
  log('finished')
})

// Version with normal function and "then"
cron.schedule('* * * * * *', () => {
  log('start')
  wait(300).then(() => log('finished'))
})

// Version with function reference
const waitFn = ms => async () => {
  log('start')
  await wait(ms)
  log('finished')
}
cron.schedule('* * * * * *', waitFn(300))
Solenoid answered 17/7 at 8:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.