我有一个名为Player的对象:
var Player = function(_id) {
var time = new Date().getTime();
this.act = function() {
if (new Date().getTime()-time>=5000)
this.destroy();
}
}
当我创建这个玩家对象时,我想在5秒后摧毁这个玩家.
现在我可以看到两种方法来解决这个问题:
>如果我决定使用act方法(使用setInterval),它可能看起来像:
Players = {};
for(var i=0;i<5;i++)
Players[i] = new Player(i);
setInterval(
function() {
for(var i=0;i<5;i++)
Players[i].act();
},
1
);
>如果我决定使用setTimeout,例如:
var Player = function() {
setTimeout(
function() {
this.destroy();
},
5000
)
}
使用方法#2意味着我不需要跟踪时间或需要特殊ID.
但是,假设我有200名玩家,它会产生200个计时器,那不是效率低下吗?
但是,如果我使用方法#1,它将一直运行,计时器将保持每毫秒运行,我觉得效率也很低.
那么,就效率而言(精确度也很好包括在内),哪种方法更好?
解
我的最终代码如下所示:
function Player(_id) {
this.enqueue(_id);
}
Player.prototype = {
queue: [],
constructor: Player,
enqueue: function (_id) {
this.id = _id;
var length = this.queue.push({
expires: new Date().getTime() + 5000,
instance: this
});
if (length === 1) this.dequeue();
},
dequeue: function () {
var player = this.queue[0];
var delay = player.expires - new Date().getTime();
setTimeout(this.act.bind(player.instance,player.id), delay);
},
act: function () {
console.log(this.id);
this.queue.shift();
if (this.queue.length)
this.dequeue();
}
};
如果我进入chrome中的开发人员控制台并输入Player(4),然后等待2秒并输入Player(3),我得到4,然后两秒钟后3.
按预期工作,通过查看代码,我只使用一个setTimeout.
解决方法:
这两个世界的优点怎么样?您正在按顺序创建Player对象.因此,它们将以与创建时相同的顺序超时.记住这一点,你一次只需要一个setTimeout(对于接下来会超时的Player对象).这是如何实现它:
function Player() {
this.enqueue();
}
Player.prototype = {
queue: [],
constructor: Player,
enqueue: function () {
var length = this.queue.push({
expires: new Date().getTime() + 5000,
instance: this
});
if (length === 1) this.dequeue();
},
dequeue: function () {
var player = this.queue[0];
var delay = player.expires - new Date().getTime();
setTimeout(this.act.bind(player.instance), delay);
},
act: function () {
this.destroy();
this.queue.shift();
if (this.queue.length)
this.dequeue();
}
};
现在,每次创建Player实例时,它都会将其添加到队列中(入队).如果队列中只有一个实例,则队列开始移动(出队).超时后,实例被销毁并且队列移位.如果队列中仍有实例,则队列继续移动.
这样,只有一个setTimeout一次处于活动状态,下一个setTimeout在第一个结束后开始.