Javascript 使用一组SetTimeout或setInterval刷新一组对象是否更有效
假设有一组Javascript 使用一组SetTimeout或setInterval刷新一组对象是否更有效,javascript,node.js,v8,spidermonkey,Javascript,Node.js,V8,Spidermonkey,假设有一组Watchers需要定期刷新。它们各自可能有不同的刷新间隔。在任何给定时刻都可能有几百个这样的观察者项目。任何观察者的刷新时间可以从一秒钟到几分钟或几小时不等 哪个更好 对每个设置使用单独的setTimeout 使用每秒运行一个函数的setInterval。然后,这些函数在每个观察程序中循环,检查是否需要刷新 起初,我假设setTimeout的本机代码实现将比执行检查的JS函数更有效,但这实际上是一个如何实现setTimeout的问题,每个超时在每个刻度上需要多少开销,以及超时数的
Watcher
s需要定期刷新。它们各自可能有不同的刷新间隔。在任何给定时刻都可能有几百个这样的观察者项目。任何观察者的刷新时间可以从一秒钟到几分钟或几小时不等
哪个更好
- 对每个设置使用单独的
setTimeout
- 使用每秒运行一个函数的
setInterval
。然后,这些函数在每个观察程序中循环,检查是否需要刷新
起初,我假设setTimeout
的本机代码实现将比执行检查的JS函数更有效,但这实际上是一个如何实现setTimeout
的问题,每个超时在每个刻度上需要多少开销,以及超时数的扩展程度如何
我问的是一个节点应用程序,所以我所指的特定引擎是V8,但如果有人也知道其他引擎的详细信息,那就太酷了。这里有一个想法应该非常有效,无论setTimeout或setInterval是如何实现的。如果您在将来的N个不同时间安排了N个事件,请创建一个对象数组,其中每个对象都具有事件到期时间的属性以及告诉您事件类型的属性(回调或其他标识符)。最初按时间属性对该数组进行排序,以便下一次在事件的前面,最远的时间在事件的末尾
然后,查看数组的前端,计算该事件发生之前的时间,并在该持续时间内执行setTimeout()。当启动setTimeout()
时,查看数组的开头并处理所有到达时间的事件。如果在处理一个事件后,您需要安排它的下一次出现,请计算将来它应该触发的时间,并从头到尾遍历数组,直到您找到它后面的事件,并在该事件之前插入该事件(以保持数组的排序顺序)。如果找不到,请将其插入末尾。在处理完到达时间的阵列前端的所有事件后,计算阵列前端事件的增量时间,并针对该间隔发出新的setTimeout()
下面是一些伪代码:
function orderedQueue() {
this.list = [];
}
orderedQueue.prototype = {
add: function(time, callback) {
var item = {}, added = false;
item.time = time;
item.cb = callback;
for (var i = this.list.length - 1; i >= 0; i--) {
if (time > this.list[i].time) {
// insert after the i item
this.list.splice(i + 1, 0, item);
added = true;
break;
}
}
// if no item was after this item,
// then put this on the front of the array
if (!added) {
this.list.unshift(item);
}
},
addDelta(delta, callback) {
var now = new Date().getTime();
this.add(now + delta, callback);
},
waitNext: function() {
// assumes this.list is properly sorted by time
var now = new Date().getTime();
var self = this;
if (this.list.length > 0) {
// set a timer for the first item in the list
setTimeout(function() {
self.process();
}, this.list[0].time - now);
}
},
process: function() {
var now,item;
// call all callbacks who's time has been reached
while (this.list.length) {
now = new Date().getTime();
if (this.list[0].time <= now) {
// remove front item from the list
item = this.list.shift();
// call the callback and pass it the queue
item.cb(this);
} else {
break;
}
}
// schedule the next item
this.waitNext();
}
}
当然可以。现在我必须找出在JS中使用链表的好方法。@下载-我添加了一个可能的实现,它只使用排序数组。好吧,没有人回答这个问题,但是你的建议很有用,所以我会给你标记。
var q = new orderedQueue();
// put initial events in the queue
q.addDelta(100, f1);
q.addDelta(1000, f2);
q.addDelta(5000, f3);
q.addDelta(10000, f4);
q.addDelta(200, f5);
q.addDelta(100, f1);
q.addDelta(500, f1);
// start processing of queue events
q.waitNext();