快速回调中的SetTimeout

时间:2018-08-24 04:02:07

标签: javascript express web-development-server

我正在创建一条路线,其中将名为“活动”的数据属性设置为true,但一小时后设置为false。我想知道在快速回调中调用settimeout函数是否可行或不好。如;

app.get("/test", (req, res) => {

//Some code

SetTimeout(func, 3600);
});

这对于缩放很不好,如果多次击打这条路线会很昂贵吗?预先感谢。

2 个答案:

答案 0 :(得分:0)

似乎您只需要设置1个计时器。假设“小时”从第一个请求开始。

let timer = null
let data = true

app.get("/test", (req, res) => {

  //Some code
  if (!timer) {
    timer = setTimeout(() => {data=false}, 3600);
  }
});

相反,对于多个用户,您可以通过将时间戳记放入哈希并针对每个请求或单独的间隔计时器对其进行轮询来避免设置多个计时器。

// init
let timers = {}

// in request
if (!timers[user]) {
    timers[user] = new Date().getTime() / 1000 + 3600
}
else if (timers[user] <= new Date().getTime() / 1000)
{
    // update db, etc
}


// or poll for expirations in separate single timer routine
let now = new Date().getTime() / 1000
Object.keys(timers).forEach(user => {
  if (timers[user] <= now) {
    // update db, etc
  }
})

答案 1 :(得分:0)

如果将这些值存储在数据库中,则不应在节点中为每个条目创建一个计时器来重置该值。尤其是如果它是一个持久的计时器,会话类/相关的数据应持续更长的时间然后几秒钟,通常不应保留在节点进程的内存中。

访问您的网站的频率越高,您越有可能在任何时间运行至少一个计时器。在这种情况下,您将无法在不丢失计时器的情况下重新启动应用程序。或者,您需要等到所有计时器都结束并且不接受任何新计时器为止。

您不能切换到群集模式,因为如果一个用户两次调用该路由,则该路由可能会出现在两个不同的进程中,其中每个进程都不知道另一个进程设置的超时时间。

因此,一个更好的主意是在数据库中添加一个时间戳,并为所有条目负责一个清理计时器。