在 Nodejs Express 应用程序中单击按钮时启动/停止 cronjob
Posted
技术标签:
【中文标题】在 Nodejs Express 应用程序中单击按钮时启动/停止 cronjob【英文标题】:Start/stop cronjob on button click in Nodejs Express app 【发布时间】:2021-07-03 08:10:06 【问题描述】:我一直在做一个项目,当用户单击前端的按钮时,它需要启动和停止 cron 调度程序。基本上,当用户单击按钮时,cron 作业将启动。单击停止按钮将停止计时器。就这么简单。
为了实现这一点,我在单击按钮时向 Nodejs/Express 后端发出发布请求,这会触发调度程序的启动/停止功能。这是端点的样子:
const cron = require('node-cron');
router.post('/scheduler', async (req, res) =>
// gets the id from the button
const id = req.body.id;
try
// finds the scheduler data from the MongoDB
const scheduler = await Scheduler.find( _id: id );
// checks whether there is a scheduler or not
if ( !scheduler )
return res.json(
error: 'No scheduler found.'
);
// creates the cronjob instance with startScheduler
const task = cron.schedule('*/10 * * * * *', () =>
console.log('test cronjob running every 10secs');
,
scheduled: false
);
// checks if the scheduler is already running or not. If it is then it stops the scheduler
if ( scheduler.isRunning )
// scheduler stopped
task.stop();
return res.json(
message: 'Scheduler stopped!'
);
// starts the scheduler
task.start();
res.json(
message: 'Scheduler started!'
);
catch(e)
console.log(e)
);
现在调度程序运行良好,但不会在第二次单击按钮时停止。它继续运行。我觉得我没有在正确的地方打电话给task.start()
和task.stop()
。而且我不知道正确的地方在哪里。我实际上是 cronjobs 的新手。
如果有人告诉我我做错了什么,那就太好了。
提前致谢。
【问题讨论】:
【参考方案1】:每次您点击scheduler api
时,都会创建一个cron-job 的新实例,并且您正在停止新定义的cron-job 实例 而不是上一个。
解决方案是定义 cron-job 超出路由器范围,这样每当您点击scheduler api
时,实例都不会改变
像这样:
const cron = require('node-cron');
// creates the cronjob instance with startScheduler
const task = cron.schedule('*/10 * * * * *', () =>
console.log('test cronjob running every 10secs');
,
scheduled: false
);
router.post('/scheduler', async (req, res) =>
// gets the id from the button
const id = req.body.id;
try
// finds the scheduler data from the MongoDB
const scheduler = await Scheduler.find( _id: id );
// checks whether there is a scheduler or not
if ( !scheduler )
return res.json(
error: 'No scheduler found.'
);
// checks if the scheduler is already running or not. If it is then it stops the scheduler
if ( scheduler.isRunning )
// scheduler stopped
task.stop();
return res.json(
message: 'Scheduler stopped!'
);
// starts the scheduler
task.start();
res.json(
message: 'Scheduler started!'
);
catch(e)
console.log(e)
);
【讨论】:
嘿伙计。你知道我们是否可以创建多个可以通过它们的 ID 停止的 cron 作业吗?例如,我启动了 cron 作业 1 和 2,现在我只想停止 cron 作业 2。我怎样才能只停止那个 cron 作业? 定义另一个超出范围的 cronjob,就像 Abhishek 为第一个 cronjob 建议的那样。 另外不要忘记在每次启动/停止后更新您的数据库中的调度程序运行状态 @Zak 这就是声明 'const task' 的用途,控制 cronjob 实例。因此,您将复制声明,但将第 2、3、4 个 cronjob 变量命名为“const task2、const task3、const task4”(或者更好的是,适当命名它们,即如果分配给 task2 的 cronjob 是“发送一些电子邮件” ,你应该把它命名为'const emailCron'。然后你可以通过对emailCron的引用来操作那个特定的对象,即:emailCron.stop();或emailCron.starat();hth! @RobLittle 非常感谢。我现在明白了!【参考方案2】:问题可能出在下面一行:
const task = cron.schedule('*/10 * * * * *', () =>
实际上,如果您阅读 node-cron 的源代码,它会创建一个新任务并使用新的调度程序: https://github.com/node-cron/node-cron/blob/fbc403930ab3165ffef7d53387a29af92670dfea/src/node-cron.js#L29
function schedule(expression, func, options)
let task = createTask(expression, func, options);
storage.save(task);
return task;
(内部使用:https://github.com/node-cron/node-cron/blob/fbc403930ab3165ffef7d53387a29af92670dfea/src/scheduled-task.js#L7:
let task = new Task(func);
let scheduler = new Scheduler(cronExpression, options.timezone, options.recoverMissedExecutions);
所以,当你打电话时:
task.stop();
据我了解,您所做的是调用全新任务的方法“停止”,而不是您第一次单击按钮时启动的任务的方法停止。
从您的代码来看,问题在于您在使用任务时实际上并没有使用调度程序。
PS: 该模块还公开了一个函数,可让您从其存储中检索任务:https://github.com/node-cron/node-cron/blob/fbc403930ab3165ffef7d53387a29af92670dfea/src/node-cron.js#L58
但由于我没有找到任何关于它的文档,我不建议使用它。
【讨论】:
嘿,谢谢你的时间。所以它有点令人困惑,因为我的模型也被命名为调度程序。哈哈。但是我从您的回答中了解到的是,第二次按钮单击实际上会创建另一个任务,而不是停止前一个任务。所以我认为我可以在这里做两件事:1: put that task variable somewhere where it won't create the second time.
或 2: call getTask() function but there's no documentation on it.
我认为我应该选择 1。你知道如何在整个设置中实现这一点吗?以上是关于在 Nodejs Express 应用程序中单击按钮时启动/停止 cronjob的主要内容,如果未能解决你的问题,请参考以下文章
Nodejs/Express 保存从 web 客户端选择头像并直接保存到 MySQL 数据库