• Web Worker


    写在前面

    众所周知,JavaScript是单线程的,JS和UI更新共享同一个进程的部分原因是它们之间互访频繁,但由于共享同一个进程也就会造成js代码在运行的时候用户点击界面元素而没有任何响应这样的情况,这么糟糕的用户体验HTML5怎么会不修订了,这样Web Worker诞生了。

    简介

    Web Worker进程加载的js运行的时候不仅不会影响浏览器UI,而且也不会影响其它Web Worker进程加载的JS代码。由于Web Worker进程加载的js运行的时候不会影响浏览器UI,也就说明Web Worker中加载的js不能修改用户界面,而每个Web Worker都有自己的全局运行环境,因为它加载的js不能修改用户界面,所以它能操作的对象主要只包括以下几个部分

    • 一个浏览器对象,只包含四个属性:appName,appVersion,userAgent,platform
    • 一个location对象(和window里的一样,但是里面所有的属性是只读的)
    • 一个self对象指向全局Web Worker线程对象
    • 一个importScripts()方法使Web Worker能够加载外部js文件
    • 所有的ECMAScript对象
    • XMLHttpRequest构造器
    • setTimeout()和setInterval()方法

    WebWorker擅长之处

    这里先特意讲一个importScript方法,它是以阻塞方法加载js的,只有所有文件加载完成之后接下来的脚本才能继续运行

    事实上,Web Worker适合于那些纯数据的,或者说与浏览器UI没关系的长运行脚本。

    下面附上最基本的demo事例,我相信聪明的你一看就会了

    简单建立一个html页面,页面代码如下而所示 

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
    </head>
    <body>
        <script type="text/javascript">
            var worker = new Worker("webworker.js"); //这句话将让浏览器去加载webworker.js
            worker.postMessage('主线程发起的数据请求!'); //把数据传递给webworker.js
    
            worker.onmessage = function (event) {
                console.log(event.data); //来自work的数据保存在event.data
                //接下来就可以对它event.data进行序列化等数据处理啦
            };
    
        </script>
    </body>
    </html>

    上面代码加载的webworker.js的代码如下所示:

    onmessage = function (event) {
        var data = event.data;//这是接收过来的数据
        console.log(data);//注意啦 这里不能用alert来替换console.log  因为alert是会阻塞ui  所以wobworker没有使用alert的权限哦
        postMessage(data + ' --- js回复过来的数据哦!');//这里可以把数据传递给主线程哦
    };
    onerror = function (event) {
        console.log('Error:' + event.filename + '(' + event.lineno + '):' + event.message);
        //event.filename  错误的文件名
        //event.lineno 错误的行号
        //event.message完整的错误消息
    }

    那么Web Worker的主要用处在哪儿呢,它的优点有哪些呢,下面总结一下哈

    • 可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信,使用ternimate方法停止工作
    • 可以在worker中通过importScripts(url)加载另外的脚本文件

    它的主要缺点在哪儿呢

    • 不能跨域加载JS
    • worker内代码不能访问DOM
    • 因为它是html5中新的API,所以各个浏览器支持都不一样哦!

    web worker来加载数据还是比较慢的,即便是大数据量情况下也没任何优势,可能是Worker初始化新起线程比较耗时间。除了在加载过程中是无阻塞的之外没有任何优势

    下面再附上我写的一个例子,主要是发挥Web Worker的特长

    html界面代码如下所示

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
    </head>
    <body>
        <script type="text/javascript">
    
            var worker = new Worker('fibonacci.js');
            worker.addEventListener('message', function (event) {
                console.time('总共花费的时间为:');
                console.log('结果:' + event.data);
                console.timeEnd('总共花费的时间为:');
            }, false);
    
            worker.postMessage(40);
    
        </script>
    </body>
    </html>

    上面代码中加载的fibonacci.js代码如下所示

    var fibonacci = function (n) {
        return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2);
    };
    onmessage = function (event) {
        var n = parseInt(event.data, 10);
        console.log('传过来的值为:'+n);
        postMessage(fibonacci(n));
    };
    onerror = function (event) {
        console.log('Error:' + event.filenme + '(' + event.lineno + '):' + event.message);
    }

    大家运行后可以发现chrome控制台的结果如下图所示:

  • 相关阅读:
    deepin15.11安装Oracle JDK
    API文档-BASE-BASE
    miniui控件的el属性(自动生成的标签)
    miniui从继承看控件处理
    miniui中的继承
    miniui加载(二)
    miniui 加载文件时会做的一些事情
    二、运行盛派的Demo(看下效果)
    一、选择云服务器和测试微信公众号Token
    绘制圆角(2)
  • 原文地址:https://www.cnblogs.com/liyunhua/p/4495542.html
Copyright © 2020-2023  润新知