【问题标题】:How to get the date every time a day passes in nodejs?如何在nodejs中每天过去时获取日期?
【发布时间】:2021-11-20 03:10:56
【问题描述】:

我打算做的是一个程序,它会向几个用户发送生日祝贺电子邮件,然后该程序将使用今天并对数据库(它是一个 Excel 文件)执行查询,其中将获取日期将用户的出生日期与当前日期进行比较,如果月份和日期一致,则会发送邮件。我觉得可以用setInterval()来完成,但不知道会不会影响程序的性能。因为会上传到我公司的windows server 2012服务器上。

我的代码:

const express = require("express");
const app = express();
const excel = require('./public/scripts/readExcel.js');
const email = require('./services/email/sendEmail.js');
     
app.post('/send-email',(req, res)=>{
  setInterval(() => {
    email.sendEmail()
    .then((result) => {
        res.status(200).jsonp(req.body);;
        console.log(result)
    }).catch((err) => {
        res.status(500).jsonp(req.body);;
        console.log(err);
    });
  }, 3600000);//1 hour
    
});
app.listen(4000, ()=>{
    console.log("Serven on -> http://localhost:4000");
})

基本上它的作用是每小时调用一次sendEmail 函数,该函数读取 Excel 文件或数据库并提取日期字段,与当前日期进行比较,然后使用 Nodemailer 将邮件发送给过生日的人。另外,setInterval 会进入“/send-email”的路线,或者如何提出请求?

【问题讨论】:

  • 你尝试过 cronJobs 吗?
  • @Mohammednaji No
  • 那你要试试cronJobs,你一定要好好理解

标签: javascript node.js dom-events nodemailer


【解决方案1】:

我将把我的答案分成两部分

  1. 您需要做什么才能使您的解决方案发挥作用
  2. 如何优化性能

1.您需要做什么才能使您的解决方案发挥作用

您需要解决两个基本问题。

一个。您的解决方案将按原样运行,您只需在启动服务器后调用/send-email 端点一次。 但是...这会带来副作用。 因为 setInterval 每小时都会调用email.sendEmail... 代码块,而这个代码块每次都会调用res.status(200).jsonp(req.body)。如果您不知道此 res.status.. 设置您收到的请求的响应。在这种情况下,您向/send-email 提出请求。这是第一次,它会正常工作,因为您正在返回对上述请求的响应。但是当第二次调用这个代码块时,它没有任何响应,因为请求已经被响应了。记住,HTTP 协议响应一次请求,然后请求就完成了。因此,由于这个原因,您的代码块 res.status... 变得无效。所以第一件事,只给res.status打一次电话。所以我会从 setInterval 代码块中删除这一行,如下所示

app.post('/send-email',(req, res)=>{
  setInterval(() => {
    email.sendEmail()
    .then((result) => {
        console.log(result)
    }).catch((err) => {
        console.log(err);
    });
  }, 3600000);//1 hour
  res.status(200).jsonp(req.body);
})

b.此外,我认为您不希望每次启动服务器时都急于调用/send-email,因此我还要确保每次启动服务器时都会启动此生日祝福代码块。因此,我将删除app.post('/send-email',(req, res)=>{ 行。也不是说我不是为了请求而调用它,我没有任何请求发送响应,所以我也可以删除res.status.. 行。你的代码现在看起来像这样

const express = require("express");
const app = express();
const email = require('./services/email/sendEmail.js');

(function(){ 
  // Birthday wish email functionality
  setInterval(() => {
    email.sendEmail()
    .then((result) => {
        console.log(result)
    }).catch((err) => {
        console.log(err);
    });
  }, 3600000);//1 hour
})() // Immediately invoked function
    

就是这样,您的解决方案现在有效。现在要发送生日祝福电子邮件,您无需执行任何其他操作,只需启动服务器即可。


现在我们进入第二部分

2。如何优化性能

一个。将间隔设置为 24 小时而不是 1 小时

为什么你需要每隔一小时检查一次生日?如果您在这里没有好的答案,我肯定会将时间间隔更改为 24 小时

b.让代码更健壮地处理大数据

只要您的 Excel 中只有 100 条条目并且它们在未来不会增长太多,我就不会让它变得更复杂以提高性能。 但是,如果您的条目注定要增长到 1000 甚至更多。我建议使用数据库(例如 mongodb、postgres 或 mysql 等)来存储您的数据并仅查询与特定日期匹配的生日条目。 我还会实现一个排队系统来处理查询和批量发送电子邮件,而不是一次完成所有这些。

【讨论】:

    【解决方案2】:

    为此,您还可以使用 npm 包 cron-job 每小时运行一次 cron 作业 使用

    var cron = require('node-cron');
    
    cron.schedule('* * 1 * *', () => {
      console.log('running a task every hour');
    });
    

    【讨论】:

    • 在部署应用程序时如何向“/send-mail”路由发出请求?
    • 在您的情况下,您不必每小时都调用路线。只需创建一个功能,您可以从 excel 中检查今天的生日,然后如果用户有生日,则发送邮件。并将该函数放入cron-job中。无需调用url
    • 所以我没有使用路由,而是使用了 cron,并在其中放置了发送电子邮件的函数?
    • 有点离题,但在这里可能会对您有所帮助。如果您需要同时容纳快速应用程序和 cron 作业,请查看干净的架构。可能通过正确的架构,您将能够重用所有业务逻辑并为 cron 作业编写一个适配器,并为 express 应用程序端点编写一个适配器(如果需要)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    • 2020-01-13
    • 1970-01-01
    • 2017-07-06
    相关资源
    最近更新 更多