如何在 JavaScript 中最好地实现轮询消费者模式

发布于 2024-09-19 07:33:01 字数 907 浏览 9 评论 0原文

背景

早在 5 月份,我就在 WebKit 上报告了一个关于 内存 的问题保留问题。看起来问题可能是由于 Web Inspector 本身造成的,但我还不确定。

问题

出现了一个问题,即我的 JavaScript 应用程序实现了“轮询消费者” “当数据可用时获取数据的模式。问题是记忆会在一天中被保留和增长。 JavaScript 逻辑是这样的:

  1. 获取数据并给我回电
  2. 当我被回电时,处理数据并 然后执行步骤 1

这是在 JavaScript 中实现轮询消费者的合理方法吗?顺便说一下,我使用的是 jQuery 的 ajax 函数,这当然可能有它自己的问题。此外,我使用 jQuery 代理作为成功处理程序,因此我认为范围内的保留不应该成为问题。我在不使用代理的情况下也观察到了这个问题。一些代码:

FidsDataController.prototype.getFids = function() {
  var self = this;
  $.ajax({
...
    success: function(data) {
      // Do some processing
      // Call back in a short while...
      setTimeout($.proxy(self.getFids, self), 100);
    },
...
  });
);

Background

Back in May I reported an issue on WebKit regarding a memory retention issue. It looks as though the problem could be due to the Web Inspector itself, but I'm not convinced yet.

Problem

A problem surfaced whereby my JavaScript application implements a "Polling Consumer" pattern for obtaining data as it becomes available. The problem is that memory is being retained and grows throughout the day. The JavaScript logic goes like this:

  1. Get the data and call me back
  2. When I'm called back process the data and
    then perform step 1

Is this a reasonable way of implementing a polling consumer in JavaScript? Incidentally I'm using jQuery's ajax function which of course may have its own problems. In addition I'm using a jQuery proxy as the success handler so I would have thought that retention through scope should not be an issue. I have also observed the problem without using proxies. Some code:

FidsDataController.prototype.getFids = function() {
  var self = this;
  $.ajax({
...
    success: function(data) {
      // Do some processing
      // Call back in a short while...
      setTimeout($.proxy(self.getFids, self), 100);
    },
...
  });
);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

任谁 2024-09-26 07:33:27

您只有一份 getFids 副本,这很好,但每次调用它时,您都会创建两个新函数:一个用于成功处理程序,另一个来自 $.proxy 打电话。这两个函数在每次调用时并不是唯一的。将它们放入可重用变量中,您将节省大量额外的函数创建,这应该会大大降低内存泄漏的可能性。

我们在构造函数中为每个对象制作一次每个函数的代理版本的示例。重复调用不会生成更多函数:

function FidsDataController() {
  // ...constructor...


  // Proxy these functions just once from the prototype
  this.getFids = $.proxy(this.getFids, this);
  this._getFids_success = $.proxy(this._getFids_success, this);
}

FidsDataController.prototype.getFids = function() {
  var self = this;
  $.ajax({
    success: this._getFids_success;
  });
};

FidsDataController.prototype._getFids_success = function(data) {
  // processing of data
  setTimeout(this.getFids, 100);
};

You have only one copy of getFids, which is good, but every time it gets called you are creating two new functions: one for the success handler and one from the $.proxy call. These two functions are not unique per call. Put them in reusable variables and you'll spare lots of extra function creation, which should lower your memory leak potential by a lot.

Example where we make proxied versions of each function once per object, in the constructor. Repeated calls will not generate more functions:

function FidsDataController() {
  // ...constructor...


  // Proxy these functions just once from the prototype
  this.getFids = $.proxy(this.getFids, this);
  this._getFids_success = $.proxy(this._getFids_success, this);
}

FidsDataController.prototype.getFids = function() {
  var self = this;
  $.ajax({
    success: this._getFids_success;
  });
};

FidsDataController.prototype._getFids_success = function(data) {
  // processing of data
  setTimeout(this.getFids, 100);
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文