但是,当我尝试在工作中发出网络请求时,请求似乎被UI线程阻止.下面是一个例子来说明这个问题:
base.js:
var worker = new Worker("/worker.js");
setTimeout(function() {
console.log("begin blocking");
var startDt = new Date();
var blockPeriod = 5000;
var a;
// ObvIoUsly we'd never actually do this,but this while loop
// is a convenient way to create the problem case (a blocked main
// thread).
while ((new Date() - startDt) < blockPeriod) {
a = 0;
}
console.log("stop blocking");
},3000);
worker.js:
var requestInterval = 1000;
var sendRequest = function() {
console.log("Send request interval");
var request = new XMLHttpRequest();
request.open("GET","/ping",true);
request.onload = function() {
if (request.status === 200){
console.log(request.responseText)
} else {
console.log(request.status)
}
};
request.onerror = function() {
console.log("error")
};
request.send();
setTimeout(sendRequest,requestInterval);
}
sendRequest();
我看到的结果是,我们看到成功的HTTP请求三秒钟,直到阻止开始.在这一点上,我们在阻止结束之前看不到任何记录到控制台的信息,此时我们看到五个“发送请求间隔”,后跟响应的5个日志,如下所示:
Send request interval
{"pong": true}
Send request interval
{"pong": true}
Send request interval
{"pong": true}
Send request interval
{"pong": true}
begin blocking
stop blocking
5x Send request interval
5x {"pong": true}
Send request interval
{"pong": true}
在我的服务器日志中,我也看到在该阻塞时间内没有请求,那么这五个请求在阻塞期结束时大致同时被接收.
假设“发送请求间隔”连续出现五次,则工作人员显然继续执行:如果不是,则不会通过排队来进行下一次迭代.我还发现,如果我通过触发一个window.alert而不是在一个循环中旋转来阻止,我将以1秒的间隔从sendRequest开始获取日志消息,然后以大批量的方式获取响应处理程序日志消息很快,我停止阻止.
在Firefox中,后台线程似乎在这种情况下完全停止(在封锁期间我没有收到同一批五个请求排队).不过,在这种情况下,我只针对Chrome(我最终想使用甚至不能在Firefox工作中使用的WebSockets),所以我对此并不感兴趣.
所有这些都加在一起,这导致我相信Web Worker中有一些类被活动的线程阻塞,有些不是(我最初看到与WebSockets相同的行为).具体来说,我想知道(如果有人知道):
> Chrome中的主线程阻止了什么工作者活动?
有没有办法解决这个问题?我非常希望能够在Worker中建立一个WebSocket连接,然后继续执行PING / PONG,即使某些事情(如警报/确认)也阻止了主线程.
这是一切废话,我只是在做一些愚蠢的事情吗?
解决方法
更糟糕的是,Chrome具有最好的行为.当UI线程被阻止时,工作者进行XHR请求:
> Chrome:所有请求都排队等待.在UI线程解除阻塞之前,浏览器实际上不会发出请求.在正面方面,工作线程仍然可以自由运行.
> Firefox:新的XMLHttpRequest()阻塞,直到UI线程解除阻塞.
> IE:xhr.open()阻塞,直到UI线程解除阻塞.
虽然Chrome幸运的是不会导致一个工作线程停止和等待(即使它不会得到任何数据),Firefox和IE会导致一个工作线程等待UI线程,当你尝试做一个XHR请求.
没有办法解决这个问题您对浏览器的支持,代表您提出请求.我没有使用WebSockets进行任何测试,但即使UI线程被阻止,他们也可能会传送事件.在最坏的情况下,接收到的消息将排队,直到UI线程解除阻塞.