美文网首页
H5 worker理解

H5 worker理解

作者: FConfidence | 来源:发表于2018-03-16 21:34 被阅读38次
  1. Chrome 浏览器的线程模型是怎样的? (操作系统=国家 内存空间 围圈厂子(进程空间 Chrome多个进程)) 生产线(线程)

    • 程序: 计算机可以执行的代码, 存在于磁盘中, 一个程序有多个进程
    • 进程: 把程序调入到计算机的内存中, 准备执行, 是活动的, 等待被CPU执行 (分配内存空间, CPU处理)
    • 线程: CPU执行进程代码的基本单位--生产任务(生产线) 多个线程之间互不影响
  2. 进程和线程的关系

    • 进程是操作系统分配内存的基本单位 (武器工厂圈地造武器, 是国家允许的基本单位)
    • 线程必须处于进程内部(每一个武器厂的生产线就是一个线程, 国家不可能直接给你生产线分配内存, 而是由线程调度)
      一个进程至少有一个线程, 也可以有多个 (8G内存可以大致创建 4000个线程, 创建2000个左右就会卡死)
  3. 多个线程之间是怎么工作的?

    • 多个线程之间是并发执行的 (宏观上同时执行的, 微观上是同步的 时间片)
    • Chrome里面的线程: JS引擎线程, GUI线程, 异步HTTP请求线程, 定时器线程, 事件处理线程
  4. 输入一个URL

    • Chrome中发起http请求最多可以使用6个并发的线程
    • chrome中负责向页面中执行绘制任务的只有一个线程- GUI线程 (只有上面的绘制才能绘制下面的, 所以一个就够了, 多了碍事) UI主线程
      • 根本解决之道: 创建一个新的线程, 去执行耗时的js任务 JavaThread = new Thread
    • H5提供类似创建新线程的机制 new Worker('wkr.js') //工人线程 专门用来执行耗时操作的, 与UI主线程并发执行, 所以UI主线程不会卡主
  5. Worker的天然缺陷

    • 不允许接触任务的BOM和DOM对象 (window, document)
    • 原因: 只能有一个渲染线程, worker允许参与GUI的话, 浏览器GUI绘画会乱掉(同时渲染会出问题)
  6. worker的用途 (真实的项目中用到的地方比较少)

    • 非常耗时的且与DOM操作无关的时候, 会用到
  7. UI主线程可以给Worker传递数据 --- 发消息, Worker线程可以给UI主线程传递数据 --- 接收消息

    • UI线程发送消息/接收消息
      worker.postMessage(value)
      worker.onmessage=function(event) {console.log(event.data)}
      
    • Worker线程接收消息/发送消息
      onmessage = function(event) {
        console.log(event.data)
        postMessage('stringData')
      }
      
  8. worker线程是不能再创建子线程worker的, worker只能与GUI主线程进行通信 (比Java的thread更加单纯)
    总结:

    1. Worker本质上是一个线程, 在UI主线程之外并发执行的线程, 用来执行耗时的JS任务
    2. 缺陷: 不能操作DOM和BOM, 只能和UI主线程发消息
    3. 实际上的复杂操作由服务器完成, 服务器比浏览器快多了
  9. H5测试代码 (需要在服务器上运行, 本地运行会出错)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>worker 和 GUI 线程之间的通信</title>
</head>
<body>
  <input type="number" id="num" value="12" min="0" max="1000">
  <button id="startBtn">开始开启worker</button>
  <p id="result"></p>
  <script>
    var btn = document.getElementById('startBtn');
    btn.onclick = function() {
      var value =  document.getElementById('num').value;
      var worker = new Worker('worker_calculate.js');
      // UI线程给worker传递消息数据
      worker.postMessage(value)

      worker.onmessage = function(event) {
        var data = event.data;
        document.getElementById('result').innerHTML = data;
      }
      // UI主线程接收主线程传递的消息
    }
  </script>
  <button onclick="console.log(1111)">button1</button>
  <button onclick="console.log(222)">button2</button>
</body>
</html>
  1. worker_cakculate.js
/*Worker接收GUI主线程的发送的消息,  接收到消息后才能开始运算*/

console.log('Worker线程待命中')

// worker中 直接写onmessage方法即可
onmessage = function(event) {
  var n = event.data; // 表示传递过来的数据
  var value = parseInt(n);
  console.log('---------从GUI主线程获取到的数据: ', value)
  console.time('休眠')
  var now = new Date().getTime();
  do {
     var cur = new Date().getTime();
  } while (cur - now <= 5000)
  console.timeEnd('休眠')
  console.log('---------返回给GUI线程的数据',  value * value)
  postMessage('你传递过来数据的平方是:' + value * value)
}

相关文章

网友评论

      本文标题:H5 worker理解

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