javascript – 一个SetInterval与多个SetTimeout

我有一个名为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在第一个结束后开始.

上一篇:javascript – FF5和chrome setInterval()的解决方法,在非活动选项卡中设置setTimeout()


下一篇:javascript – 在设定的时间量后取消requestAnimationFrame