Search code examples
javascriptnode.jsasync-awaitpromisees6-promise

Promise is not working in Cron Job in NodeJS


Promise is not working inside cronjob in nodejs.

let me explain my question with this code.

I have one cron that running in every five seconds.

Now Inside a cron I have one function client.statistics and I think it's take some time. so I need to wait for that and then after below code run.

Issue: Issue is I use that code without promise so I know without promise it not worked. now I use promise for wait for that function time but currently not working.

I use promise and now my out like this.

output: --- CRON START --- DATE-TIME 2021-10-22 11:41:10

it's not executing below code, don't know what happen here

What I need: I need First Execute Top Code then Promise Code then last code like console like end cron.

Thank you advanced. :)

const twelvedata = require("twelvedata");

cron.schedule('*/5 * * * * *', () => {
    var today = new Date();
    var datetime = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate() + ' ' + today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
    console.log('--- CRON START ---');
    console.log('DATE-TIME', datetime);
    let symbol = "5PAISA";
    let params = {
        symbol:symbol,
        exchange: "NSE",
        country: "India",
    };

    let mypromise = function functionOne(){
        const client = twelvedata(config);
        return new Promise((resolve ,reject)=>{
            client.statistics(params).then((data) => {
                console.log("All Worked",data);
                resolve("Resolved");
            }).catch((error) => {
                console.log('Error', error);
                reject("Rejected")
            });
        });
    };

    mypromise().then((res)=>{
        console.log(`The function recieved with value ${res}`)
        console.log('--- CRON END ---');
        return datetime;
    }).catch((error)=>{
        console.log(`Handling error as we received ${error}`);
        console.log('ERROR');
        return false;
    });

    console.log('--- CRON FINISHED ---');

});

Solution

  • First your new Promise((resolve ,reject)=>{ … }) is an anti-pattern, because inside of that you create a promise chain.

    Also reject("Rejected") is often considered as an anti-pattern because the reject("Rejected") is considered to be equivalent to the meaning of throw "Rejected" and you should only throw actual errors.

    console.log('--- CRON FINISHED ---'); does not wait for the promise chain to be finished but is called immediately.

    Here a cleaned-up version of your code.

    const twelvedata = require("twelvedata");
    
    cron.schedule('*/5 * * * * *', () => {
      var today = new Date();
      var datetime = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate() + ' ' + today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
      console.log('--- CRON START ---');
      console.log('DATE-TIME', datetime);
    
      let symbol = "5PAISA";
      let params = {
        symbol: symbol,
        exchange: "NSE",
        country: "India",
      };
    
    
      twelvedata(config)
        .statistics(params)
        .then((data) => {
          console.log("All Worked", data);
          return "Resolved"
        }).catch((error) => {
          console.log('Error', error);
          return "Rejected"
        }).then((res) => {
          console.log(`The function recieved with value ${res}`)
          console.log('--- CRON END ---');
          // you don't make use of this returned value in your code ?
          // return datetime;
        }).catch((error) => {
          console.log(`Handling error as we received ${error}`);
          console.log('ERROR');
          // you don't make use of this returned value in your code ?
          // return false;
        })
        .finally(() => {
          console.log('--- CRON FINISHED ---');
        });
    
    
    });
    

    As I said the reject("Rejected") is an antipattern and in your case it is not clear why you even translate the actual error to Rejected you could just let the error pass through to your console.log(`Handling error as we received ${error}`);.

    const twelvedata = require("twelvedata");
    
    cron.schedule('*/5 * * * * *', () => {
      var today = new Date();
      var datetime = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate() + ' ' + today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
      console.log('--- CRON START ---');
      console.log('DATE-TIME', datetime);
    
      let symbol = "5PAISA";
      let params = {
        symbol: symbol,
        exchange: "NSE",
        country: "India",
      };
    
    
      twelvedata(config)
        .statistics(params)
        .then((data) => {
          console.log("All Worked", data);
          return "Resolved"
        })
        .then((res) => {
          console.log(`The function recieved with value ${res}`)
          console.log('--- CRON END ---');
          return datetime;
        })
        .catch((error) => {
          console.log(`Handling error as we received ${error}`);
          console.log('ERROR');
          return false;
        })
        .finally(() => {
          console.log('--- CRON FINISHED ---');
        });
    
    
    });
    

    Using async and await can make the whole thing even more clearer.

    const twelvedata = require("twelvedata");
    
    cron.schedule('*/5 * * * * *', async() => {
      var today = new Date();
      var datetime = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate() + ' ' + today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
      console.log('--- CRON START ---');
      console.log('DATE-TIME', datetime);
    
      let symbol = "5PAISA";
      let params = {
        symbol: symbol,
        exchange: "NSE",
        country: "India",
      };
    
      // I commented that out because you acutall don't use that in your code, but is would it shows how to match your `return` statements in the promise chain.
      // let result;  
      try {
        const data = await twelvedata(config).statistics(params)
        console.log("All Worked", data);
        const res = "Resolved"
    
        // result = datetime;
        console.log(`The function recieved with value ${res}`);
        console.log('--- CRON END ---');
      } catch (error) {
        // result = false;
        console.log(`Handling error as we received ${error}`);
        console.log('ERROR');
      }
    
      // console.log(result)
    
      console.log('--- CRON FINISHED ---');
    
    });
    

    And removing everything that does not seem to be used:

    const twelvedata = require("twelvedata");
    
    cron.schedule('*/5 * * * * *', async() => {
      var today = new Date();
      var datetime = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate() + ' ' + today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
      console.log('--- CRON START ---');
      console.log('DATE-TIME', datetime);
    
      let symbol = "5PAISA";
      let params = {
        symbol: symbol,
        exchange: "NSE",
        country: "India",
      };
    
      try {
        const data = await twelvedata(config).statistics(params)
        console.log("All Worked", data);
        console.log('--- CRON END ---');
      } catch (error) {
        console.log(`Handling error as we received ${error}`);
        console.log('ERROR');
      }
    
    
      console.log('--- CRON FINISHED ---');
    
    });