无法弄清楚在 React 应用程序中启动 CronJob 的位置

Can't figure out where to initiate CronJob in react app

我有一个 React 应用程序,它必须每周一早上 7:58 执行每周任务。该任务设置为单独的函数 "notification()"。我想使用 NPM 的 'CRON' 包在适当的时候调用 notification() 。

我将 CRON 包裹在这样的函数中:

let mondayNotif = () => {
  new CronJob('* 58 7 * * 2', function() {

    notification()

  }, null, true, 'America/Los_Angeles');
};

我的问题:我应该在哪里调用函数 mondayNotif(),以确保正确启动 CronJob?一开始以为一定是在后端,但是npm包好像不支持server-side。但是,如果我在客户端调用 mondayNotif(),如果站点处于非活动状态,CronJob 是否仍会发生?

据我所知,React JS 是前端——它在客户端运行。你需要一个服务器。在这种情况下,基于 node.js 的服务器。从理论上讲,如果没有人打开该网站,则 React js 将不会启动任何内容。查看如何在 node.js

上安排 cron 作业

enter link description here

挪威,从客户端调用CronJob,因为如果有100个用户,CronJob将被触发100次。您肯定需要在服务器端安装它

我找到了自己的答案。但首先,关于 CronJobs 的一些见解会对我有所帮助:

  1. CronJobs 本质上是一个带有嵌入式时钟的第三方函数。一旦他们是 "initiated",您就不必打电话给他们了。第三方根据您在参数中安排的时间(即:“30 6 * * 5”)远程调用它们。

  2. 不同博客关于CRON时间有些出入。例如一些博客坚持有 6 个时间变量,但我发现它适用于 5.

  3. CronJobs 应该位于与主代码主体不同的文件中,通常位于文件夹结构的顶部,靠近 "package.json" 和 "server.js" 文件。

  4. 直接在 cronjob.js 文件中设置所有 CronJob 实用程序似乎是最干净的。例如:我直接在 cronjob.js 中使用单独的数据库连接并完全绕过 api 路由。

  5. CronJobs 应该只在应用启动时启动一次。有几种方法可以做到这一点:package.json 或 server.js 是最明显的选择。

这是我最终使用的文件结构:

-App
--package.json
--server.js
--cronjob.js
--/routes 
--/src
--/models
--/public

...然后我将 cronjob.js 导入 "server.js"。这样,当 server.js 文件在 "dev" 或 "build" 期间加载时,cronjob 功能将启动一次。

作为参考,这里是原始 cronjob.js 文件(用于电子邮件通知):

const CronJob = require('cron').CronJob;    

const Department = require('./models/department.js');
const template_remind = require('./config/remindEmailTemplate.js');

const SparkPost = require('sparkpost');
const client = new SparkPost('#############################');

const mongoose = require("mongoose");
const MONGODB_URI =
      process.env.MONGODB_URI || "mongodb://localhost:27017/app";
    mongoose.Promise = Promise;

// -------------------------- MongoDB -----------------------------

// Connect to the Mongo DB
mongoose.connect(MONGODB_URI, { useNewUrlParser: true }, (err, db) => {
  if (err) {
    console.log("Unable to connect to the mongoDB server. Error:", err);
  } else {
    console.log("Connection established to", MONGODB_URI);
  }
});

const db = mongoose.connection;

// Show any mongoose errors
db.on("error", error => {
  console.log("Mongoose Error: ", error);
});

// Once logged in to the db through mongoose, log a success message
db.once("open", () => {
  console.log("Mongoose CRON connection successful.");
});

// ------------------------ Business Logic --------------------------

function weekday(notifications) {
    Department.find({"active": true, "reminders": notifications, "week": {$lt: 13}}).distinct('participants', function(err, doc) {
        if(err){
            // console.log("The error: "+err)
        } else {
            console.log("received from database... "+JSON.stringify(doc))
            for(let i=0; i<doc.length; i++){
                client.transmissions.send({
                    recipients: [{address: doc[i]}],
                    content: {
                        from: 'name@sparkmail.email.com',
                        subject: 'Your email notification',
                        html: template_remind()
                    },
                    options: {sandbox: false}
                }).then(data => {})
            }
        }
    })
}

function weeklyNotif() {

    new CronJob('45 7 * * 1', function() {weekday(1)}, null, true, 'America/New_York');
    new CronJob('25 15 * * 3', function() {weekday(2)}, null, true, 'America/New_York');
    new CronJob('15 11 * * 5', function() {weekday(3)}, null, true, 'America/New_York');
}

module.exports = weeklyNotif()

如您所见,我设置了唯一的数据库连接和电子邮件服务器连接(与我的 API 文件分开),以及 运行 这个文件中的所有逻辑,然后导出启动功能。

这是 server.js 中出现的内容:

const cronjob = require("./cronjob.js");

你在这里所要做的就是需要文件,因为它是作为函数导出的,这会自动启动 cronjob。

感谢阅读。如果您有反馈,请分享。