首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当对象不再被引用时使用clearInterval?

当对象不再被引用时使用clearInterval?
EN

Stack Overflow用户
提问于 2018-04-30 03:23:03
回答 2查看 201关注 0票数 2

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

代码摘要:

代码语言:javascript
复制
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);
    }
}
EN

回答 2

Stack Overflow用户

发布于 2018-04-30 03:37:58

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

代码语言:javascript
复制
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);
    }
}

然后当你需要的时候:

代码语言:javascript
复制
WSClient.interval.clearInterval();
票数 2
EN

Stack Overflow用户

发布于 2018-04-30 04:22:14

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

我推荐的是,这是一种简单的方法,因为你已经定义了你的get Latency(),就是在其中加入一些逻辑,以监控是否有人在一段时间内实际要求延迟。如果getter最近一直在运行,那么就继续轮询。如果没有,则删除间隔。

如果您定义了async getLatency(),那么可以让这件事变得更容易,这样,如果您检测到延迟最近没有被pinged,您可以等待等待,直到重新计算延迟。

我没有运行这段代码,但我将其包括在内是为了说明这个想法:

代码语言:javascript
复制
// 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,而是使用重复出现的setTimeout。间隔的问题是,它是基于它自己的时钟。它不会考虑完成ping所需的时间。例如,如果你每秒轮询一次,但是需要500ms来完成ping,这是可以的,但是如果需要2000ms来ping,那么你的ping实际上会变得无序。它可能看起来像是你有一个慢得多的ping,因为你收到的ping返回的时间比最近运行得快的ping花费的时间更长。更好的做法是做一个setTimeout,只在最后一个完成后运行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50090440

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档