微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – Chrome工具主线程阻止的Web Worker

我有一个 Web Worker.我想定期网络请求.我特别想要的是即使主要的JS执行线程被阻止(例如通过一个window.alert)来进行这些请求.我正在使用Chrome 38.

但是,当我尝试在工作中发出网络请求时,请求似乎被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,即使某些事情(如警报/确认)也阻止了主线程.
这是一切废话,我只是在做一些愚蠢的事情吗?

解决方法

你的观察是正确的.当UI线程被阻止时,不调度网络调用.

更糟糕的是,Chrome具有最好的行为.当UI线程被阻止时,工作者进行XHR请求:

> Chrome:所有请求都排队等待.在UI线程解除阻塞之前,浏览器实际上不会发出请求.在正面方面,工作线程仍然可以自由运行.
> Firefox:新的XMLHttpRequest()阻塞,直到UI线程解除阻塞.
> IE:xhr.open()阻塞,直到UI线程解除阻塞.

虽然Chrome幸运的是不会导致一个工作线程停止和等待(即使它不会得到任何数据),Firefox和IE会导致一个工作线程等待UI线程,当你尝试做一个XHR请求.

没有办法解决这个问题您对浏览器的支持,代表您提出请求.我没有使用WebSockets进行任何测试,但即使UI线程被阻止,他们也可能会传送事件.在最坏的情况下,接收到的消息将排队,直到UI线程解除阻塞.

原文地址:https://www.jb51.cc/js/153335.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐