我正在尝试允许用户从客户端设置警报并将其传递到服务器。然后服务器有一个 setTimeout 倒计时,当时间用完时,执行该函数。
第一部分工作正常,但是,如果客户决定取消该特定警报,我需要能够清除相同的超时。
注:我一直在用Redis存储各种数据,所以可用。
var client = redis.createClient();
io.set("store", new sio.RedisStore);
io.sockets.on('connection', function (socket) {
socket.on('alarm:config', function(list, date, time, bool) {
if (bool) {
var now = new Date().getTime();
var year = date[0],
month = date[1] - 1,
day = date[2];
var hour = time[0],
minutes = time[1];
var alarm = new Date(year, month, day, hour, minutes);
var countdown = alarm - now;
var myAlarm = setTimeout(function() {
// do stuff...
}, ( countdown ) );
} else {
clearTimeout(myAlarm);
}
});
});
我想到的方法是使用 bool 值来确定用户是在设置还是取消该特定警报。 我意识到设置一个局部变量“myAlarm”是行不通的,我只是把它放在那里以传达这个想法。
我正在尝试找出一种方法来存储对该确切超时的引用,以便下次使用 false bool 值触发“alarm:config”套接字事件时,它可以取消之前设置的超时。
这可能是另一个问题,但是像 Google Calendar 这样的应用程序如何存储日期和时间,然后确切地知道何时触发它以及提供取消它的能力?这本质上是相同的想法。
更新:我使用以下解决方案让它工作。我愿意接受更优雅的解决方案。
socket.on('alarm:config', function(list, date, time, bool) {
var alarmName = "timer:" + list;
if (bool) {
client.hset(alarmName, "status", true);
var now = new Date().getTime();
var year = date[0],
month = date[1] - 1,
day = date[2];
var hour = time[0],
minutes = time[1];
var alarm = new Date(year, month, day, hour, minutes);
var countdown = alarm - now;
setTimeout(function() {
client.hget(alarmName, "status", function(err, bool) {
if(bool == 'true') {
// do stuff...
} else {
console.log("This alarm has been canceled.");
}
});
}, ( countdown ) );
} else {
console.log('canceling alarm');
client.hset(alarmName, "status", false);
}
});
最佳答案
根据您构建的应用程序的大小,有多种选择。
处理队列
您可以重组您的应用程序以使用作业队列而不是简单地设置计时器。这样做的好处是您可以在将来将其拆分为多个进程,但它确实使处理变得有点复杂。
类似Kue 的图书馆仅使用 Redis,并允许您延迟放置以设置将来的事件。
来自 Kue 自述文件:
var kue = require('kue')
, jobs = kue.createQueue();
// Create delayed job (need to store email.id in redis as well)
var email = jobs.create('email', {
title: 'Account renewal required',
to: 'tj@learnboost.com',
template: 'renewal-email'
}).delay(minute).save();
// Process job
jobs.process('email', function(job, done){
email(job.data.to, done);
});
// Cancel job
email.remove(function(err){
if (err) throw err;
console.log('removed completed job #%d', job.id);
});
存储对超时的引用
这不太健壮,但可以让您非常简单地完成它。它使全局变量四处 float ,并且在进程崩溃时无法恢复。
基本上,您将计时器存储在一个全局变量中,并根据作业 ID 取消它。
var myAlarms = {}
socket.on('alarm:config', function(list, date, time, bool) {
var alarmName = "timer:" + list;
if (bool) {
myAlarms[alarmName] = setTimeout(function() {
// do stuff...
}, countdown);
} else {
clearTimeout(myAlarms[alarmName]);
}
}
注意:此代码均未经过测试,可能包含错误。
关于javascript - 从客户端设置和清除 Node 服务器上的超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14176811/