zoukankan      html  css  js  c++  java
  • js多线程(worker)

        浏览器端js是单线程执行,所以当js执行高负载运算时,UI渲染就会阻塞,页面就会出现卡顿,用户体验就不是很好

        js为此也提供了异步操作,例如: 定时器(setTimeout 和 setInterval),Ajax请求等,但异步终究还是单线程,不能从根本上解决问题,像setTimeout并不能拿到正确的值,因为执行的时候将该任务放到主线程执行,只有当前面的任务执行完才开始执行,所以即使设置时间为0,也并不一定立刻执行

       所以HTML5标准添加了Web Worker,worker允许一段js程序运行在主线程之外的线程,子线程与主线程互不干扰,当子线程的代码执行完成,将结果返回给主线程,主线程接收到相应结果后再做对应处理,当有一些计算密集型或高延迟的任务就可以交给worker子线程来负担,主线程就不会阻塞

       worker是window对象的一个方法,一个worker对象可通过构造函数(window.worker())来创建,创建对象时,需要传给构造函数一个js文件,该文件包含了放到子线程中运行的代码

       worker通过postMessage()和onmessage = () => {} 来进行通信,主线程和子线程通信是双向的,都有可以发送和接收信息,postMessage传递的数据都是拷贝传递(ArrayBuffer除外)

       子线程运行耗损系统资源,所以当执行完毕后,我们可以手动关闭子线程

        在主线程中关闭: worker.terminate()

        在子线程中关闭: self.close()  (在子线程中window需改写成self,下文有解释)

       

         worker限制

         1)同源

            分配给worker子线程运行的脚本文件,必须与主线程的脚本文件同源,包括协议,域名和端口,不支持本地地址(file://);

            当使用CDN来存储js文件时,主线程与子线程就会出现跨域

            解决方法: 【1】将子线程的脚本转换成Blod对象

                            【2】然后给Blod对象创建一个URL

                            【3】将这个URL传给worker的构造函数

           示例代码: 

              var workerBlob = new Blob(['(' + function +')()'], { type: "text/javascript" });

              var url = window.URL.createObjectURL(workerBlob);

              var worker = new Worker(url);

        2) 访问 

            worker子线程所在的全局对象,与主线程不在一个上下文环境,所以无法读取主线程所在网页的DOM,无法使用document,window,parent这些对象,global指向有变更,window需要改写成self,不能执行alert()和comfire()的方法,只能读取部分navigator对象内的数据

       3)使用异步

            worker子线程中支持js的异步操作,但仍然不可以跨域

        worker的兼容性还不错,但不兼容IE9

      

  • 相关阅读:
    模板模式变形
    理解volatitle带来的可见性
    数据库隔离级别
    Spring对POST内容进行处理的坑
    动态加载JS和CSS
    MySQL性能优化总结
    JS自执行匿名函数
    CDATA为何物?
    如何编写高效的jQuery代码
    war和war exploded区别
  • 原文地址:https://www.cnblogs.com/yezi-dream/p/10202593.html
Copyright © 2011-2022 走看看