我要写一个定时每秒检查数据,求个大神解答。
发布于 6 年前 作者 yiranrucianjing 3478 次浏览 最后一次编辑是 5 年前 来自 问答

===我要写一个定时每秒检查数据,然后再根据情况做出处理,这样写会不会有递归一直不结束导致内存溢出等情况。 求大神给个好的实现方式 <pre><code> (function timing(){ // 定时1秒后执行 setTimeout(function(){ // 模拟处理耗时2秒 setTimeout(function(){ // 处理结束 console.log(‘end case’); timing(); }, 2000); }, 1000); })(); </code></pre>

14 回复

按你上面这个写法,不会的。

@alsotang 新手,不懂,不会就好,不然运行几分钟就挂了,那就悲剧了。谢谢解答

setTimeout 不是递归,请放心使用

一直回调呢?一层调一层。

用在商业逻辑部分可以在设计上规避,pub/sub更合理,维护上用cron

cron 不会用,而且下一次调用要等待当前处理结束后在执行。

这样循环,每次产生的变量所占内存都不释放,node的垃圾回收做不到内部嵌套主动释放内存,跑到后面内存吃的越来越多,里面如果有大的内存消耗,循环不了多少时间内存就爆掉了。

cron 搜索一下,教程很多。

node-schedule

用任务池处理也行。部分代码如下:

var Pool = require(‘generic-pool’).Pool;

function Task (options) { this.init(options); } util.inherits(Task, EventEmitter);

Task.prototype.init = function init (options) { var self = this; var defaultOptions = { maxConnections: 1, //同时执行数量 priorityRange: 10, //任务优先级 rateLimits: 5000, //执行完后5秒再执行 retryTimeout: 10000,//执行失败延时压入队列再次执行 };

self.options = _.extend(defaultOptions, options);

if (self.options.rateLimits !== 0) self.options.maxConnections = 1;
self.pool = Pool({name: 'crawler', max: self.options.maxConnections, priorityRange: self.options.priorityRange, create: function(callback) { callback(1);}, destroy: function() {}});
self.plannedQueueCallsCount = 0;
self.queueItemSize = 0;
self.on('pool:release', function(opt) {
    self.queueItemSize--;
    if (opt._poolReference) self.pool.release(opt._poolReference);
    if (self.queueItemSize + self.plannedQueueCallsCount === 0) self.emit('pool:drain');
});
self.on('pool:drain', function() {
    if (self.options.onDrain) {
        self.options.onDrain();
    }
});

}; Task.prototype.queue = function queue (opt) { setTimeout(function() { self._doTask(opt); }, self.options.rateLimits); }

我想要实现的功能比如一笔交易订单有超时时间,我需要每秒检查一下有没有订单超时了,如果超时了要更新数据,和新增别的数据,所以在执行的过程中有耗时,需要执行完本次操作后,重新进入每秒检查。

###我现在的实现方式如下:求大神用更好的方式实现。### <pre><code> // 检查数据函数 function caseCheck(callback){ // … callback(); };

(function timing(){ // 定时每秒检查 setTimeout(function(){ caseCheck(function(err){ if(err){ // Error:… } timing(); }); }, 1000); })(); </code></pre>

fn = ->
  task()
  setTimeout fn, n

这种代码算是模拟实现了尾递归优化. setTimeout里的fn是在next tick里执行的, 没有堆栈溢出危险.

@abbshr 那我这样写没有问题吧?

@yiranrucianjing 是的, 你要关注的只是scope/context是否能被释放和代码结构的问题.

回到顶部