Web Workers 入门学习

什么是Web Workers?

Web Workers是HTML5提供的一个JavaScript多线程解决方案。

实例说明

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Workers Study</title>
</head>
<body>
    <input type="text" placeholder="数值" id="num">
    <button id="btn">计算</button>
    <script>
        // 1 1 2 3 5 8 13 21 f(n) = f(n-1) + f(n-2)
        function fibonacci(n) {
            return n<=2 ? 1 : fibonacci(n-1)+fibonacci(n-2);
        }
        var input = document.getElementById("num");
        document.getElementById('btn').onclick = function() {
            var number = input.value;
            var result = fibonacci(number);
            var t = Date.now();
            alert(result);
            console.log(Date.now() - t);
        }
    </script>
</body>
</html>

网页输入一个数字12,弹出框显示结果为144,Console窗口显示运行时间为890毫秒。

如果输入数字50,则要过1.7分钟才会出现弹出窗口显示结果12586269025。在1.7分钟期间,页面处于“计算状态”,不能在输入框输入数字。

Web Workers解决尴尬

Web Workers将负责该计算,同时不冻结页面(计算的同时可以在输入框输入数字)。

Web Workers负责的计算属于子线程,子线程受控于主线程,且不得操作DOM。因此,该标准没有改变JS单线程的本质。

以上代码通过Web Wokers处理,实际代码如下显示:

  • WebWorkers.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Workers Study</title>
    <!-- <script type="text/javascript" src="work.js"></script> -->
</head>
<body>
    <input type="text" placeholder="数值" id="num">
    <button id="btn">计算</button>
    <script type="text/javascript">
        var input = document.getElementById("num");
        document.getElementById('btn').onclick = function() {
            var number = input.value;
            // 创建一个worker对象
            var worker = new Worker('worker.js');
            // 向分线程发送消息
            worker.postMessage(number);
            console.log('主线程向分线程发送数据' + number);
            // 绑定接收消息监听(异步事件,位置放在那里没关系)
            worker.onmessage = function (event) {
                console.log('主线程接收分线程返回的结果' + event.data);
                alert(event.data);
            }
        }
    </script>
</body>
</html>
  • woker.js

在浏览器中输入file:///c:/SuniorYang/iLearn/js/WebWorkers.html,输入数字12,点击“计算”,报错!!

Uncaught DOMException: Failed to construct 'Worker': Script at 'file:///C:/SuniorYang/iLearn/js/worker.js' cannot be accessed from origin 'null'.
    at HTMLButtonElement.document.getElementById.onclick (file:///C:/SuniorYang/iLearn/js/WebWorkers.html:18:26)
document.getElementById.onclick @ WebWorkers.html:18

因为worker不同访问本地文件,所以会提示错误。

解决方案

  1. npm install -g http-server
  2. http-server

启动http-server之后,在浏览器输入http://127.0.0.1:8080/js/WebWorkers.html,输入数字12,点击“计算”

页面响应时间较短,可以正常弹出计算结果和打印消息。如果输入数字50,则计算时间较长。

计算期间,可以在页面输入新数字52。

图解代码执行过程

worker任务作为异步任务存放在消息队列中,等待执行栈中的主线程为后返回异步执行结果。应用:城市下拉列表选择某一城市后,位于该城市下面的乡镇对加载显示。

Web Workers不足

  • 不足一:运行比较慢

使用分线程,不是因为速度快,而是因为不堵塞主线程,不冻结主界面

  • 不足二:worker内代码不能访问DOM

worker.js

// 1 1 2 3 5 8 13 21 f(n) = f(n-1) + f(n-2)
function fibonacci(n) {
    return n<=2 ? 1 : fibonacci(n-1)+fibonacci(n-2);
}

var onmessage = function(event) { // 不能用函数声明
    var number = event.data; // 通过event获得主线程发送来的数据
    console.log('分线程接收到主线程发送的数据:' + number);
    var result = fibonacci(number);
    postMessage(result); // 将获取到的数据发送给主线程
    console.log('分线程向主线程返回数据:'+result);
	alert(result);
}

alert(result); 无法运行。console是浏览器方法,与window无关。

alert是window的方法,在分线程中无法使用。分线程对象不是window,所有分线程无法更新界面。

这就是与JS是单线程不冲突的原因。

  • 不足三:不能跨域访问

跨域:www.baidu.com,通过baidu.com访问 sina.com

参考链接:

web work:  https://www.bilibili.com/video/av83803819/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值