H5之Worker多线程

1. 为什么js是单线程的?

因为我们要响应用户的一些dom操作,如果是多线程的话,那么可能dom操作同时进行了,那么给用户展示的结果就混乱了。因此我们应该等待用户操作完成之后再响应下一个的操作,所以说js一直是一个单线程的语言。

2. 什么是web worker呢?

web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验。

3. web worker的作用和好处是什么?

web worker的作用:就是为JavaScript创造多线程环境,允许主线程创建worker线程,将一些任务分配给后者运行。在主线程运行的同时,worker线程在后台运行,两者互不干扰。等到worker线程完成计算任务,再把结果返回给主线程。
web worker的好处:一些计算密集型或高延迟的任务,被worker线程负担了,主线程就会很流畅,不会被阻塞或拖慢。

4. web worker的使用场景

大型数据计算、计时器、异步请求、访问navigator部分属性、js核心对象。

5. web worker的局限性

  1. 同源限制。分配给worker线程运行的脚本文件,必须与主线程的脚本文件同源。
  2. DOM限制。worker线程无法读取主线程所在网页的DOM对象,无法使用document、window、parent这些对象。但是,worker线程可以使用navigator对象和location对象。
  3. 脚本限制。worker线程不能执行alert()方法和confirm()方法,但是可以使用XMLHttpRequest对象发出的AJAX请求。
  4. 文件限制。worker线程无法读取本地文件,它所加载的脚本,必须来自网络。
  5. 通信联系。通过postmessage和onmessage通信。

    6. 如何使用web worker

注意:需要在放在服务器下面,可以自己开一个模拟的服务器(window系统下面的可以下载一个wamp、mac系统下面的可以下载一个mamp)

1
2
3
4
5
6
// 主进程文件
var worker = new Worker("worker.js"); // Worker中添加的参数worker.js就是创建的子线程的文件(注意:在Worker中写的是子线程worker.js文件的地址)
worker.postMessage(10); // postMessage()方法是把值传给子线程
worker.onmessage = function(e){ // 当子线程把计算之后的值返回给主进程的时候,主进程会响应onmessage事件,onmessage事件中可以把值取出来
console.log(e.data);
}
1
2
3
4
5
// worker.js文件(子线程)
onmessage = function(e){ // 子线程通过onmessage来接收主线程传过来的值
var num = e.data;
postMessage(num * 100); // 子线程通过postMessage()方法,将一系列复杂的运算(在这里随便写了一个计算来代替复杂的运算)求得的值返回给主线程
}

此时控制台会打印出来:
10
1000

7. 结束web worker

  1. close()方法:在worker文件中使用,它是子线程的,你可以把它理解为:我自己辞职了;
  2. terminate()方法:在worker对象上调用(worker.terminate),它是主线程的,你可以把它理解为:我被公司炒鱿鱼了。
    如:
    使用close()方法:
    1
    2
    3
    4
    5
    6
    // 主进程文件
    var worker = new Worker("worker.js");
    worker.postMessage(10);
    worker.onmessage = function(e){
    console.log(e.data);
    };
    1
    2
    3
    4
    5
    6
    7
    // worker.js子线程文件
    close();
    onmessage = function(e){
    console.log(e.data);
    var num = e.data;
    postMessage(num * 10);
    }
    此时控制台的结果是什么都不会打印出来

使用terminate()方法:

1
2
3
4
5
6
7
8
9
10
// 主进程文件
var worker = new Worker("./worker/worker.js");
worker.postMessage(10);
worker.onmessage = function(e){
console.log(e.data);
if(e.data === 1000){
worker.terminate();
worker.postMessage(20);
}
};
1
2
3
4
5
6
// worker.js子线程文件
onmessage = function(e){
console.log(e.data);
var num = e.data;
postMessage(num * 100);
}

控制台打印出来的内容为:
10
1000

web worker现在使用不是很广,但是大家还是需要了解一下。