【发布时间】:2021-10-02 10:44:38
【问题描述】:
我的 API 中有一个计划选项,就像我使用 Expressjs 和 NodeJS 所做的那样。我们的后端使用两个参数(用户 ID 和时间戳)调用此 API。目标是在指定时间(..或几分钟后)删除用户信息(文件夹、文档等)。时间戳可以是从现在起 5 分钟到 2 天。
当它发生时,工作完成并且 API 正在等待另一个调用。该 API 每天可以接收 1000 次调用,因此性能非常重要。将来运行该功能的最佳方式是什么?
async function scheduledAction(userId, timestamp) {
var actionInFuture = await checkDate(timestamp);
if(actionInFuture) {
console.log('Action triggered');
}
}
async function checkDate(timestamp) {
await new Promise(resolve => {
setTimeout(resolve, 1000)
});
// timestamp = 1627311533000
if(Date.now() >= timestamp) {
return true;
} else {
return checkDate(timestamp);
}
}
app.get('/action', (req, res) => {
scheduledAction(req.query.userId, req.query.timestamp);
}
scheduledAction(req.query.userId, req.query.timestamp);
【问题讨论】:
-
你听说过setTimeout吗?这将阻止您的代码进行最终导致堆栈溢出的紧密递归 - 除非 v8 具有适当的尾递归 - 您是否在代码中注意到了这个问题?
-
您没有任何类型的延迟,因此您将不断地处理您的代码。然后,一旦您达到目标时间,您的代码就会运行,然后在服务器重新启动之前它不会再次运行。这是你的意图吗?
-
哦,并且 Date.now 以毫秒为单位,因此您的触发器设置为 1970 年 1 月 19 日:p 这就是为什么您可能没有遇到太多递归问题(不是堆栈溢出,因为我之前说过)
-
尝试像这样在 JS 中编写调度程序不会奏效。 Js 是单线程的,所以一旦你阻塞了线程,其他任何东西都不会运行。 SetTimeout 可能会起作用,但不能保证它的执行时间。
-
您需要以某种方式保存状态。如果您重新启动服务器,您将丢失计时器。
标签: javascript node.js sleep