美文网首页
web Worker多线程与离线缓存

web Worker多线程与离线缓存

作者: 心存美好 | 来源:发表于2022-05-18 18:29 被阅读0次

1. web Worker多线程

1.1 了解web worder

JS单线程的问题

  1. 一次只能做一件事。会造成阻塞
  2. 多核 CPU 中,单线程无法发挥计算机的计算能力

Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。

worker好处:

  1. 计算密集型或高延迟的任务被worker现成负担了,不会被阻塞或拖慢

worker的问题:

  1. Worker 线程一旦新建成功,就会始终运行, 会浪费资源,所以不用要及时关闭
1.2 主线程
1. 创建worker线程

主线程通过new命令,调用Worker()构造函数,新建一个 Worker 线程。

var worker = new Worker('work.js');

Worker()构造函数的参数是一个脚本文件,该文件就是 Worker 线程所要执行的任务。由于 Worker 不能读取本地文件,所以这个脚本必须来自网络。如果下载没有成功(比如404错误),Worker 就会默默地失败。

2. 主线程向Worker线程发布数据

主线程通过调用worker.postMessage()方法,向 Worker线程 发消息。

worker.postMessage('Hello World');

postMessage()方法的参数:

就是主线程传给 Worker 的数据。它可以是各种数据类型,包括二进制数据。

3. 主线程监听Worker线程发送的信息

主线程通过worker.onmessage指定监听函数,接收子线程发回来的消息。

worker.onmessage = function (event) {
    // 获取worker线程传递过来的数据
  console.log(event.data);
}

通过事件对象的data属性可以获取 Worker 发来的数据。

4. 关闭Worker线程

在Worker 完成任务以后,主线程就可以把它关闭

worker.terminate();
1.3 Worker 线程
1. 监听主线程发布的数据

Worker 线程通过监听message事件。来获取主线程发布的数据

self.addEventListener('message', function (e) {
  self.postMessage( e.data);
}, 

self代表子线程自身,即子线程的全局对象。

事件对象的data属性包含主线程发来的数据。

2. 向主线程发布消息

Worker线程通过self.postMessage()方法用来向主线程发送消息。

self.postMessage( e.data);
3. 关闭自身线程

Worker 线程 可以通过 close方法关闭Worker线程

self.close();
例子:

两个同步语句,不存在阻塞问题

 <body>
 <div id="box"></div>
  <div id="wrap"></div>
  <script>
    //两个同步语句,不存在阻塞问题
    box.innerHTML='111'
    wrap.innerHTML ='222'
   </script>

存在阻塞问题的语句,前面同步完成后才能渲染222

 <div id="box"></div>
  <div id="wrap"></div>
  <script>
    
    //存在阻塞问题的语句,前面同步完成后才能渲染222
    document.onclick = function () {
      let count = 0;
      for (let i = 0; i < 1000000; i++) {
        count++
      }
      box.innerHTML = count;
      wrap.innerHTML = 222
    }
   </script>

先打印主线程,再打印子线程(理解子线程)

  <div id="box"></div>
  <div id="wrap"></div>
  <script>
    //先打印主线程,再打印子线程(理解子线程)
    document.onclick = function () {
      // let count = 0;
      // for (let i = 0; i < 1000000; i++) {
      //   count++
      // }
      // 创建一个子线程
      console.log('主线程11')
      let work =new Worker('worker.js')//需要创建worker.js文件,写点内容console.log('子线程');console.log(this === self)//this 与 self都表示当前子线程对象。控制台最终结果是子线程最后打印
      console.log('主线程work',work)
      // box.innerHTML = count;
      wrap.innerHTML = 222
    }
    </script>

主线程将复杂的任务放在子线程中执行,并向子线程发送数据

// index.html(主线程中的代码)
<body>
  <div id="box"></div>
  <div id="wrap"></div>
  <script>
    document.onclick = function () {
      // 第一步创建一个子线程
      let work = new Worker('worker.js')//需要创建worker.js文件,写点内容console.log('子线程');console.log(this === self)//this 与 self都表示当前子线程对象。控制台最终结果是子线程最后打印
      //第二步 将复杂的任务放在子线程中执行,并向子线程发送数据
      work.postMessage(10000000);
      //  第三步 主线程监听事件接收子线程数据
      work.addEventListener('message', function (ev) {
        console.log('work ev', ev)
        box.innerHTML = ev.data;   //先渲染222,然后再渲染这里的值1000000。这样就不会阻塞 wrap.innerHTML = 222的执行
        this.terminate()//这里执行完了,子线程还是在工作的,所以要通过主线程关闭子线程(外部关闭子线程)。也可在子线程内部关闭self.close()
      }, false)
      wrap.innerHTML = 222
    }
  </script>
</body>
//worker.js(子线程中的代码)
//子线程接收数据,监听message事件
this.addEventListener('message', function (ev) {
    console.log(ev)//控制台中就能看到事件对象,事件对象中的data就是传过来的数据
    let count = 0;
    for (let i = 0; i < ev.data; i++) {
        count++
    }
    //   console.log(count)
    // 子线程通过this 或self把结果传给主线程
    this.postMessage(count)
    // self.close()//关闭线程
}, false)
1.4 多线程注意点
  1. 同源限制: Worker线程运行的脚本文件必须与主线程的脚本文件同源
  2. DOM限制: Worder线程中不能使用document,window,parent的对象
  3. 文件限制: Worder 线程无法读取本地文件,所加载的必须是网络文件

2. 离线存储 (offline application)

HTML5 中可以让我们构建一个离线缓存的应用, 需要创建cache manifest

什么是离线存储

离线存储是让web应用在离线的情况下继续使用, 通过manifest文件指明需要缓存的资源

2.1 离线缓存的优势
  1. 可以配置需要缓存的资源

  2. 离线浏览 - 用户可在应用离线时使用它们

  3. 速度 - 已缓存资源加载得更快, 增强用户体验

  4. 减少请求,缓解服务器负担

2.2 缓存清单

缓存清单就是一个普通的文件,其中列出浏览器应该缓存的资源,以供离线时访问. 推荐使用.appcache为后缀名

2.3 缓存使用

html标签里使用缓存清单

<--离线时也能访问到这个页面,在html标签里加上 manifest="xxxxx.appcache"就可以。将来浏览器就会请求这个文件,这个文件里说明哪些文件需要缓存,哪些文件不需要缓存-->
   
<html lang = "en" manifest="xxxxx.appcache">   
2.4 manifest(appcache) 文件格式
  1. 顶行写 CACHE MANIFEST

  2. CACHE: 指定我们需要缓存的静态资源, 入css, image, js等

  3. NETWORK: (可选) 指定需要在线访问的资源, 可以使用通配符

  4. FALLBACK: (可选) 当被缓存的文件找不到时的备用资源

2.5 其他
  1. CACHE 可以省略, 这种情况下需要缓存的资源写在CACHE MANIFESR

  2. 可以指定多个CACHE: NETWORK, FALLBACK 无顺序限制

  3. 表示注释

CACHE MANIFEST
#这是需要缓存资源CACHE:
/index.html/222.jpg/333.jpg
#表示必须在有网络的情况下使用NETWORK:
/index.css*
#如果缓存的资源找不到使用备用资源FALLBACK:
/222.jpg /333.jpg

在个互联网中能区分文件类型,因为所有的文件都有一个MIME( 多用途互联网邮件扩展类型 )

MIME参考手册https://www.w3cschool.cn/media_mimeref.html

相关文章

网友评论

      本文标题:web Worker多线程与离线缓存

      本文链接:https://www.haomeiwen.com/subject/paiaurtx.html