有关nodejs的Timers的文档说setTimeout将返回timeoutId http://nodejs.org/api/timers.html#timers_cleartimeout_timeoutid
当我在网络浏览器中使用javascript时,我会得到一个整数作为返回值。
var b = setTimeout(function(){console.log("Taco Bell")})
// b = 20088
当我使用node并执行相同的操作时,返回
var b = setTimeout(function(){console.log("Taco Bell")})
// { _idleTimeout: 60000,
// _idlePrev:
// { _idleNext: [Circular],
// _idlePrev: [Circular],
// ontimeout: [Function] },
// _idleNext:
// { _idleNext: [Circular],
// _idlePrev: [Circular],
// ontimeout: [Function] },
// _onTimeout: [Function],
// _idleStart: Wed Jan 30 2013 08:23:39 GMT-0800 (PST) }
我想要做的是将setTimeout整数存储到redis中,然后再将其清除。 所以我尝试做这样的事情
var redis = require('redis');
var redisClient = redis.createClient();
var delay = setTimeout(function(){console.log("hey")}, 20000);
var envelope = { 'body' : 'body text', 'from' : 'test@test.com', 'to' : 'test@test.com', 'subject' : 'test subject', 'delay' : delay };
redisClient.hset("email", JSON.stringify(envelope), redis.print);
但是我从JSON.stringify得到一个关于无法处理循环对象的错误。有没有办法让setTimeout返回ID或将足够的对象存储到redis中以便以后清除?
答案 0 :(得分:1)
我将对setTimeout的调用包装成一个函数,该函数将setTimeout的结果存储在一个对象中,这样你就可以通过它们的id来检索超时。
类似的东西:
var timeouts = {};
var counter = 0;
function setTimeoutReturnsId(callback, delay) {
var current = counter++;
timeouts[current] = setTimeout(function() {
timeouts[current] = null;
callback();
}, delay);
return current;
}
function getTimeoutFromId(id) {
return timeouts[id];
}
当然,当您的节点服务器重新启动时,您需要清除redis。
答案 1 :(得分:1)
我真的不相信在nodejs中(我很喜欢)你会被迫做出这样的功能。
幸运的是,setTimeout的返回有一个未记录的方法(setInterval也有它!),名为close
var timer = setInterval(doSomething, 1000);
setTimeout(function() {
// delete my interval
timer.close()
}, 5000);
希望它有用
答案 2 :(得分:0)
在此之前我一直不停地努力,所以这里有一个现代的技巧:
在最新版本的节点中,node timers为此使用Symbols;一个计时器对象具有三个符号键。我需要将计时器的唯一ID添加到我的开发调试日志中,但是当我没有该计时器系统的专用符号时,在手柄映射中查找该字段是一个障碍。
(如果需要在生产环境中方便地打印 ,则采用唯一的方法是像接受的答案那样实现整个外观;但是构建该外观只是为了调试一些棘手的计时器交互,再次撕掉它是我要调试的代码的太多变异。)
我发现的唯一错误是使用util.inspect来对不可字符串化进行字符串化,并且由于我只保留了足够长的时间来调试当前模块,因此我不必担心另一个具有相同描述性的Symbol字符串从发行版中潜入或添加其他库:
function getId(timer) {
var ids = Object.getOwnPropertySymbols(timer); // this currently returns three symbols
var key;
ids.forEach(id => {
if (util.inspect(id) === 'Symbol(triggerId)') key = id;
});
if (!key) throw new Error('Symbol(triggerId) not found in timer');
return timer[key];
}