多个 Web Worker ajax 请求,但并非所有请求都返回
Multiple Web Worker ajax requests and not all returning
我在 Web worker 中有以下代码:
self.addEventListener('message', function(e){
try {
var xhr=new XMLHttpRequest()
for(var i = 0; i < e.data.urls.length;i++){
xhr.open('GET', e.data.urls[i], true);
xhr.setRequestHeader('Accept', 'application/json');
xhr.send(null);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200 || xhr.status == 304 || xhr.status ==0) {
postMessage(xhr.responseText);
} else {
postMessage(xhr.status + xhr.responseText);
throw xhr.status + xhr.responseText;
}
}
};
}
} catch (e) {
postMessage("ERROR:"+e.message);
}
}, false);
e.data.urls 包含 16 个请求,这些请求在 UI 线程上处理,如下所示:
var replies = 0;
worker.addEventListener('message', function(e){
replies += 1;
});
仅完成 10 个请求,这是因为 UI 线程在所有请求返回之前已停止,还是我缺少其他内容?
这里发生的事情是你的xhr
变量在循环中被覆盖。由于XMLHttpRequest
的性质,也就是说,默认情况下它是异步的,在xhr.send();
行执行不等待之后for
进入下一个循环,并且xhr.[...]
行在上一个循环中设置和触发的xhr
对象上运行。根据前一个循环的请求是否返回(以及因此执行的状态更改处理程序)或是否返回(这是非常不可预测的),您可以覆盖"实时"或"Finshed"xhr
对象。那些在完成之前被覆盖的将丢失。
您应该确保不会覆盖。不要对同一个 XMLHttpRequest 对象进行操作,而是为每个请求实例化一个新对象。
我将处理程序函数的定义移到了循环之外。无需在每个循环中重新定义它。它是在分配给它的 XMLHttpRequest 实例的上下文中调用的,因此this
指向该实例。
此外,我交换了xhr.send()
和xhr.onreadystatechange = ...
线。应在发送请求之前分配状态更改事件处理程序(从发送开始就触发了多个事件),尽管不太可能,但在代码中执行添加事件处理程序的行之前,请求甚至可能返回就绪状态 4。
self.addEventListener('message', function(e){
var xhrs = [];
function handler() {
if (this.readyState == 4) {
if (this.status == 200 || this.status == 304 || this.status ==0) {
postMessage(this.responseText);
} else {
postMessage(this.status + this.responseText);
throw this.status + this.responseText;
}
}
};
for(var i = 0; i < e.data.urls.length;i++) {
xhrs[i] = new XMLHttpRequest();
xhrs[i].open('GET', e.data.urls[i], true);
xhrs[i].setRequestHeader('Accept', 'application/json');
xhrs[i].onreadystatechange = handler;
xhrs[i].send(null);
}
}, false);
您的示例与此 Firefox 示例类似,除了 worker 内部的循环发出多个 ajax 请求。我很想知道是什么导致了失败。您可能会遇到单个工作线程可以处理的并发 ajax 连接数的限制。
您能否尝试将循环的网址移动到主 gui 线程:
for(var i = 0; i < urls.length; i++){
worker.postMessage(urls[i]);
}
并将您的工作线程更改为一次只执行一个 Ajax 调用?
self.addEventListener('message', function(e){
try {
var xhr=new XMLHttpRequest()
xhr.open('GET', e.data, true);
xhr.setRequestHeader('Accept', 'application/json');
xhr.send(null);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200 || xhr.status == 304 || xhr.status ==0) {
postMessage(xhr.responseText);
} else {
postMessage(xhr.status + xhr.responseText);
throw xhr.status + xhr.responseText;
}
}
};
} catch (e) {
postMessage("ERROR:"+e.message);
}
}, false);
看看这是否有效?
Mozilla 示例有一些错误处理程序,可能会揭示问题。您可以尝试在主 GUI 线程中添加:
worker.onerror = function(error) {
dump("Worker error: " + error.message + "'n");
throw error;
};
在工人内部:
function errorReceiver(event) {
throw event.data;
}
- JSONP请求返回结果,但也触发error_callback
- "日期“;AJAX请求返回的类型值未定义
- Ajax请求返回空的数据字符串,但首先得到了正确的数据
- 如何显示从Ajax请求返回的数组.使用Yii2
- WordPress Ajax请求返回0
- Ajax请求返回模块设置数据
- JSON请求返回.txt文件
- 如何检索 AJAX 请求返回的数据
- 对服务器的 GET 请求返回 net::ERR_CONNECTION_REFUSED
- 为什么我的猫鼬对象 Id 请求返回一个空数组
- 请求返回 unicode 替换字符
- ajax请求返回me“;错误404”;即使资源存在
- Pingfederate opentoken模块CORS请求返回302,而不是200
- 修改Ajax请求返回的JSon格式
- node.js请求返回对象
- AJAX请求返回Javascript获胜't返回特定函数,但将返回其他函数
- 为什么我的ajax请求返回一个空响应
- 我的Ajax请求返回成功,但脚本不是't已执行
- 从Ajax请求返回数据
- HUE API JavaScript HTTP PUT请求返回;net::ERR_EMPTY_REPONSE”;