Home > Enterprise >  Promise is not working in Cron Job in NodeJS
Promise is not working in Cron Job in NodeJS

Time:10-22

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 ---');

});

CodePudding user response:

instead of returning a new promise in the functionOne try to assign a promise to the mypromise variable.

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

Now use it without calling:

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;
    }).finally(() => {
        console.log('--- CRON FINISHED ---')
    })

CodePudding user response:

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 ---');

});

CodePudding user response:

You don't need your own promise based wrapper API, because the api you're using already returns promises

Consider rewriting the code so you aren't using so many promises and nested callbacks.

This (untested) version of the code has only 2 levels of indentation , no callbacks (ignoring that its all in a call to cron.schedule), and is 6 lines shorter.

const twelvedata = require("twelvedata");

cron.schedule('*/5 * * * * *', async () => {
    try
    {
        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",
        };
    
        const client = twelvedata(config);
        const data = await client.statistics(params);
        console.log(`The function recieved with value ${data}`)
        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 ---');
    }

});
  • Related