是的,据我所知,每个请求的默认池限制为 10,默认请求超时为 30 秒,但是可以控制超时和轮询限制,并且不同的浏览器实现不同的限制!
查看这个Google 实施。
这是捕捉超时错误的一个很棒的实现!
您可以在这里找到 Firefox 的详细信息!
Internet Explorer 的细节是从 Windows 注册表内部控制的。
也看看这个问题。
基本上,您控制的方式不是通过更改浏览器限制,而是通过遵守它们。因此,您应用了一种称为节流的技术。
将其视为创建函数的 FIFO/优先级队列。将 xhr 请求作为成员并在它们之间强制延迟的队列结构是 Xhr 轮询。例如,我正在使用 Jsonp 从位于另一个域的 node.js 服务器获取数据,当然由于浏览器的限制,我正在轮询。否则,我从服务器得到零响应,这仅仅是因为浏览器的限制。
我实际上正在为每个应该发送的请求做一个控制台日志,但并不是所有的请求都被记录下来。所以浏览器限制了它们。
我会更具体地帮助你。我的网站上有一个页面,该页面应该呈现数十甚至数百篇文章的视图。您可以使用很酷的水平滑块浏览它们。
滑块的当前值与当前的“页面”匹配。由于我每页只显示 5 篇文章,而且我无法完全加载数千篇文章“onload”而不会对性能产生严重影响,因此我加载了当前页面的文章。我通过向 Python 脚本发送跨域请求来从 MongoDB 获取它们。
该脚本应该返回一个包含五个对象的数组,其中包含我为“页面”构建 DOM 元素所需的所有详细信息。但是,有几个问题。
首先,滑块工作得非常快,因为它或多或少是一个值变化。即使有拖放功能、按键事件等,实际更改也需要几毫秒。但是,滑块的代码如下所示:
goog.events.listen(slider, goog.events.EventType.CHANGE, function() {
myProject.Articles.page(slider.getValue());
}
slider.getValue() 方法返回一个带有当前页码的 int,所以基本上我必须从以下位置加载:
currentPage * articlesPerPage to (currentPage * articlesPerPage + 1) - 1
但是为了加载,我做了这样的事情:我有一个存储引擎(把它想象成一个数组):
- 我检查内容是否已经存在
- 如果是,则没有必要再发出请求,因此请继续从数组中获取 DOM 元素,并将已创建的 DOM 元素放在适当的位置。
如果不是,那么我需要得到它,所以我需要发送我提到的那个请求,它看起来像(不考虑浏览器限制):
JSONP.send({'action':'getMeSomeArticles','start':start,'length': itemsPerPage, function(callback){
// 现在我只是快速解析回调以确保它是一致的 // 创建 DOM 元素,并填充客户端存储 // 并为用户更新视图。}}
问题来自您更改该滑块的速度。由于每个更改都应该触发一个请求(正常的 Xhr 请求也会发生同样的情况),所以您基本上跨越了所有浏览器的限制,所以如果没有限制,大多数请求都不会有“回调”。'callback' 是 JSONP 请求返回的 JS 代码(这更像是一个远程脚本包含而不是其他任何东西)。
所以我所做的是将请求推送到优先级队列,而不是 POLL,因为现在我不需要同时发送多个请求。如果队列为空,则执行最近添加的成员,每个人都很高兴。如果不是,则取消所有正在进行的未完成请求,仅执行最后一个请求。
现在,在我的特定情况下,我进行二进制搜索(0(log n))以查看存储引擎是否还没有先前请求的数据,这会告诉我先前的请求是否已完成。如果有,则将其从队列中删除并处理当前的,否则将触发新的。如此等等。
同样,为了速度考虑和讨厌的浏览器,如 Internet Explorer,我提前 3-4 步执行上述过程。所以我提前预加载了 20 页,直到一切都是客户端存储引擎。这样,每个限制都被成功处理。
冷却时间由滑过 20 页所需的最短时间覆盖,并且节流确保在任何给定时间不超过 1 个活动请求(向后兼容至 Internet Explorer 5)。
我写这一切的原因是为了给你一个例子,试图说明你不能总是直接从 FIFO 结构中强制延迟,因为你的调用可能需要变成用户看到的,而你并不完全想要用户等待 10-15 秒以呈现单个页面。
此外,始终尽量减少轮询和轮询的需要(同时触发 Ajax 事件,因为并非所有浏览器实际上都对它们做了好事)。例如,与其发送一个请求以获取内容并发送另一个请求以在您的应用指标中查看要跟踪的内容,不如在服务器级别执行尽可能多的任务!
当然,您可能希望正确地跟踪您的错误,因此您选择的库中的 Xhr 对象为 ajax 实现错误处理,并且因为您是一个了不起的开发人员,所以您想使用它们。
所以假设你有一个 try - catch 块 场景是这样的:一个 Ajax 调用已经完成,它应该返回一个 JSON,但是调用不知何故失败了。但是,您尝试解析 JSON 并使用它做任何您需要做的事情。所以
function onAjaxSuccess (ajaxResponse) {
try {
var yourObj = JSON.parse(ajaxRespose);
} catch (err) {
// Now I've actually seen this on a number of occasions, to log that an error occur
// a lot of developers will attempt to send yet another ajax request to log the
// failure of the previous one.
// for these reasons, workers exist.
myProject.worker.message('preferrably a pre-determined error code should go here');
// Then only the worker should again throttle and poll the ajax requests that log the
//specific error.
};
};
虽然我已经看到各种实现尝试同时触发尽可能多的 Xhr 请求,直到遇到浏览器限制,然后在等待浏览器“冷却”时停止未触发的请求方面做得很好',我可以建议您考虑以下几点:
- 速度对您的应用程序有多重要?
- I/O 的可扩展性和密集程度如何?
如果第一个的答案是“非常”,而后者的答案是“OMFG 现代技术”,那么尽量优化你的代码和架构,这样你就不需要同时发送 10 个 Xhr 请求。此外,对于大型应用程序,多线程您的流程。实现这一点的 JavaScript 方法是使用工作者。或者你可以打电话给 ECMA 委员会,告诉他们将其设为默认值,然后将其发布在这里,以便我们其他 JS 开发人员可以享受 JS 中的原生多线程:)(他们怎么没想到这个?! ?!)