clearInterval何时不再引用对象?

时间:2018-04-29 19:23:03

标签: javascript typescript clearinterval

我有一个类作为服务器的客户端(通过WebSocket)。我想实现一个定期ping服务器以确定延迟的系统。但是,我担心如果我为了这个目的在类中使用setInterval,它将继续尝试在对象应该被垃圾收集后ping。我怎么知道何时致电clearInterval

代码摘要:

class WSClient extends EventEmitter
{
    private latency: number;
    public get Latency(): number
    { return this.latency; }

    public async ping(): Promise<number>
    { ... }

    public constructor(options)
    {
        super();

        // Do constructor stuff

        setInterval(() => this.ping().then(latency => this.latency = latency), 1000);
    }
}

2 个答案:

答案 0 :(得分:2)

您可以使用setInterval()并将其保存到变量中,然后您可以像这样访问该时间间隔:

class WSClient extends EventEmitter
{
    private latency: number;
    public get Latency(): number
    { return this.latency; }

    public async ping(): Promise<number>
    { ... }

    public constructor(options)
    {
        super();

        // Do constructor stuff

        this.interval = setInterval(() => this.ping()
        .then(latency => this.latency = latency), 1000);
    }
}

然后当你需要:

WSClient.interval.clearInterval();

答案 1 :(得分:1)

这就是事情:你永远不会达到对象“应该”被垃圾收集的点,因为你定义的setInterval持有对该对象的引用(在你的上下文中,为{{ 1}})永远。您将需要一些额外的逻辑来确定是否仍需要运行它。

我推荐的是,这是一个简单的方法,因为你已经定义了this,就是在那里放一些逻辑来监控是否有人在一段时间内确实要求延迟。如果最近运行了getter,请继续进行轮询。如果没有,请删除间隔。

如果您定义get Latency(),那么如果您发现延迟最近没有被ping过,那么您可以这样做更容易,您可以等到重新计算延迟。

我没有运行这个,但是我想用它来说明这个想法:

async getLatency()

另外,您可能要考虑不使用// ms to wait until cancelling the interval const latencyTimeout = 200000; // In your class async getLatency(): number { if (!this.latency) { const started = Date.now(); const poller = setInterval(async () => { if (Date.now() - started > latencyTimeout) { clearInterval(poller); this.latency = null; } this.latency = await this.ping(); }, 1000); this.latency = await this.ping(); } return this.latency; } ,而是使用定期setInterval。间隔的问题在于它基于自己的时钟。它不会考虑完成ping所需的时间。例如,如果你每秒轮询一次,但是完成ping需要500ms,那就没关系,但是如果ping需要2000ms,那么你的ping实际上会出现故障。看起来你的ping速度要慢得多,因为你收到ping的返回时间超过了最近运行速度快的ping。最好做一个setTimeout,而不只是在最后一个完成之后运行。