Promise 在 NodeJS 的 Cron Job 中不起作用

Promise is not working in Cron Job in NodeJS

Promise 在 nodejs 的 cronjob 中不起作用。

让我用这段代码解释一下我的问题。

我有一个 cron,每五秒 运行一次。

现在在 cron 中我有一个函数 client.statistics 我认为这需要一些时间。所以我需要等待,然后在下面的代码 运行.

之后

问题: 问题是我在没有承诺的情况下使用该代码,所以我知道在没有承诺的情况下它不起作用。现在我使用 promise 等待该功能时间但目前不工作。

我使用 promise,现在我是这样的。

输出: --- CRON 开始 --- 日期时间 2021-10-22 11:41:10

它没有执行下面的代码,不知道这里发生了什么

我需要什么:我需要先执行Top Code然后Promise Code然后last code 像 console 像 end cron。

谢谢先进。 :)

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

});

不要在 functionOne 中返回一个新的承诺,而是尝试将一个承诺分配给 mypromise 变量。

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")
                 });
               });

现在不用调用就可以使用了:

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

首先你的 new Promise((resolve ,reject)=>{ … }) 是一个反模式,因为你在其中创建了一个承诺链。

另外,reject("Rejected") 通常被认为是一种反模式,因为 reject("Rejected") 被认为等同于 throw "Rejected" 的含义,您应该只抛出实际错误。

console.log('--- CRON FINISHED ---'); 不等待承诺链完成,而是立即调用。

这是您的代码的清理版本。

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


});

正如我所说,reject("Rejected") 是一种反模式,在您的情况下,不清楚为什么您甚至将实际错误转换为 Rejected,您可以让错误传递给您的 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 ---');
    });


});

使用asyncawait可以使整个事情更加清晰。

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

});

并删除所有似乎没有用到的东西:

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

});

您不需要自己的基于承诺的包装器 API,因为您正在使用的 api 已经 returns 承诺

考虑重写代码,这样您就不会使用太多的承诺和嵌套回调。

这个(未经测试的)版本的代码只有 2 级缩进,没有回调(忽略它全部在对 cron.schedule 的调用中),并且缩短了 6 行。

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

});