【问题标题】:Is there a way to limit the number of AJAX calls in the browser that remain open?有没有办法限制浏览器中保持打开状态的 AJAX 调用的数量?
【发布时间】:2011-07-27 18:26:18
【问题描述】:

我有一个软件设计问题,关于处理依赖于多个(但大多是连续的,而不是同时的)对服务器的短期 AJAX 调用的客户端 JavaScript 程序的最佳方式是什么?对用户交互的响应[在我的特殊情况下,它将是一个 facebook-GAE/J 应用程序,但我相信这个问题与任何客户端(浏览器)/服务器设计有关]。

首先,我问了这个问题:What is the life span of an ajax call?。基于 BalusC 的回答(我鼓励它阅读它there),简短的回答是“这取决于浏览器”。所以,现在我无法真正控制服务器发送响应后发生的事情。

  • 如果 AJAX 调用的主要用途是从服务器仅检索一次数据,是否可以手动销毁它? xhr1.abort() 会这样做吗?

  • 或者,最好的选择就是这样?手动关闭每个连接(如果可能的话)会不会给每个调用增加太多开销?

  • 是否可以手动设置每个域的限制?

  • 最后(但并非最不重要!),我真的应该担心这个吗?多少次调用足以开始延迟浏览器(特别是一些带有 BalusC 在另一个问题中提到的泄漏错误的 IE 浏览器?请记住,这是我的第一个 javascript/java servlets 项目。

提前谢谢你

【问题讨论】:

  • 我不是真正的 UI 或 JavaScript 程序员,可能是错的,但我似乎记得你可以保持多少连接有某种上限(取决于浏览器)同时向同一主机打开(我认为这就是为什么像地图应用程序使用不同命名的域来通过多个连接获取数据的原因)
  • @esaj:这是并发连接,是的,有一个限制。该限制取决于浏览器。它可以低至 2,并且在很长一段时间内一直那么低。最近的桌面浏览器往往更多地在 6-8 范围内,但移动浏览器坚持较低的数字。
  • 所以浏览器限制已经很低(我期待它会更大)
  • 是的,但同样,这是对并发连接的限制,我真的,真的应该在上面说它是每台服务器。因此,与 S3 或 www 服务器的连接不超过六个。这是几年前的一个很好的综述:stevesouders.com/blog/2008/03/20/…

标签: java javascript ajax servlets


【解决方案1】:

XHR 的使用范例是您不必担心对象会发生什么——浏览器的引擎会在幕后为您处理这些事情。因此,我认为尝试手动“改进”事情没有任何意义。浏览器开发人员当然知道 99.9999% 的 JS 程序员不这样做,因此他们不仅考虑到了这一点,而且还可能针对这种情况进行了优化。

你不应该担心它,除非你手上有一个具体的问题。

至于限制每个域的 AJAX 调用数量(并发未完成的调用,或发出的总调用,或您可能感兴趣的任何其他指标),解决方案将是古老的 CS 经典:添加另一层抽象。

在这种情况下,额外的抽象层将是一个函数,所有 AJAX 调用都将通过该函数进行路由;然后,您可以实现跟踪每个呼叫的进度(如果您愿意,可以按域)并根据该状态拒绝或推迟来电的逻辑。正确获得它并不容易,但它肯定是可行的。

但是,我建议您也不要担心这个,除非您手头有具体问题。 :)

更新:

浏览器确实对并发 AJAX 调用实施了自己的限制;这里有一个很好的问题:How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?

另外,正如 TJ Crowder 在 cmets 中提到的那样:确保在使用完 XHR 对象后没有保留对它们的引用,以便它们可以被垃圾收集——否则,你正在创建 自己的资源泄漏。

第二次更新:

有一篇关于重用 XHR here 的好博文——它实际上是相关博文 的开始。不利的一面是,它已经过时了,并没有得出任何实际的结论。但它很好地涵盖了重用 XHR 的机制。

【讨论】:

  • +1 只是作为一个辅助:确保您不会意外挂在对 XHR 对象的任何引用。这完全是您的问题,而不是浏览器的问题。
  • @Jon 有趣的选择。你能以这种方式重用 XMLHttpRequest 还是没有意义?
  • @T.J. Crowder 所有的请求都是作为局部变量在短函数中创建的,所以我想我已经涵盖了。到目前为止,我试图避免任何全局变量
  • @Aleadam:听起来你的状态很好,只要你没有创建 long-lived 闭包或任何东西(短期很好;正常,事实上)。
  • @Aleadam:再次更新——查看那篇博文。
【解决方案2】:

如果 AJAX 调用的主要用途是只从服务器检索一次数据,是否可以手动销毁它? xhr1.abort() 会这样做吗?

它只中止正在运行的请求。它不会关闭连接。

或者,最好的选择就是这样?手动关闭每个连接(如果可能的话)是否会给每个调用增加太多开销?

不可能。这是浏览器的责任。

是否可以手动设置每个域的限制?

从服务器端不可能。这是特定于浏览器的设置。最好的办法是在某些页面对话框中要求最终用户更改设置(如果尚未完成)。但这毕竟没有任何意义,如果最终用户完全不理解这背后的基本原理,那肯定是没有意义的。

最后(但并非最不重要!),我真的应该担心这个吗?多少次调用足以开始延迟浏览器(特别是一些带有 BalusC 在另一个问题中提到的泄漏错误的 IE 浏览器?请记住,这是我的第一个 javascript/java servlets 项目。

是的,您当然应该担心浏览器特有的错误。您希望您的应用程序能够正常工作,对吗?为什么不直接使用现有的 ajax 库,如 jQuery?它已经为您处理了所有令人讨厌的错误和细节(这不仅仅是 MSIE 内存泄漏)。只需拨打$.ajax()$.get()$.post()$.getJSON() 即可。当您对材料相当陌生时,我不会尝试重新发明 XHR 处理轮。您可以在this answer 中找到一些 jQuery-Servlet 通信示例。

【讨论】:

  • 确实,我开始使用 jQuery 进行调用。我在示例中使用了纯 JavaScript,因为它比其他任何东西都更像是一个概念性问题。此外,这就是为什么在上一个关于通话寿命的问题中,我询问 $.post() 是否表现相同,认为可能会对连接进行一些响应后处理。我从您之前的回复中了解到,它主要涵盖了浏览器特定的创建。我会仔细阅读那段代码,但我肯定会错过很多实现细节。
猜你喜欢
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多