JS线程机制与事件机制

JS线程机制与事件机制

1.进程与线程

(1).定义:

  • 进程:程序的一次执行,它占有一片独有的内存空间

  • CPU的基本调度单位,是程序执行的一个完整的流程

(2).进程与线程的关联

  • 一个进程一般至少有一个运行的线程:主线程

  • 一个进程可以运行多个线程

  • 一个进程内的数据可以供其中的多个线程共享

  • 多个线程之间的数据是不能直接共享的

(3).浏览器基本上是多进程的

2.浏览器内核

(1).定义:支持浏览器运行的最核心的程序

(2).不同的浏览器运行的内核不同

  • Chrome,Safari:webkit

  • firefox:Gecko

  • IE:Trident

  • 国内浏览器360等:Trident + webkit

(3).内核组成的模块:

  • html,css文档解析模块:负责页面文本的解析

  • dom/css模块: 负责dom/css在内存中的相关处理

  • 布局和渲染模块:负责页面的布局和效果的绘制

  • 定时器模块:负责定时器的管理

  • 网络请求模块:负责服务器请求(Ajax)

  • 事件响应模块:负责事件的管理

3.定时器

(1)分类:

  • 循环定时器:不关闭一直执行

  • 延时定时器:一定时间后才执行,只执行一次

(2)循环定时器:setInterval

 1     var i = 0;
 2     //获得定时器句柄
 3     var intervalId = setInterval(function(){
 4       if (i >= 5) {
 5         //清除定时器
 6         clearInterval(intervalId);
 7       }
 8       console.log(Date.now());
 9       i++;
10     },1000);

(3)延时定时器:

1     setTimeout(function(){
2       console.log("----");
3     },2000);

4.JS是单进程的

(1)证明:

  • 使用setTimeout()回调函数在主线程运行

  • 定时器回调函数只有在运行栈中的代码全部执行完毕后才可能执行

(2)为什么js要使用单线程模式:

  作为浏览器的脚本语言主要目的是和用户交互,以及操作DOM,单线程会避免复杂的同步问题

(3)代码分类:

  • 初始化代码

  • 回调代码

(4)JS引擎执行代码的基本流程

  1. 先执行初始化代码:包括一些特别的代码:

    • 设定定时器

    • 绑定监听

    • 发送Ajax请求

  2. 在某一时刻执行回调代码

5.事件循环模型

执行流程:

1.同步任务加载执行

初始化代码:绑定监听,设置定时器,发送ajax请求

2.异步任务交给时间管理模块

3.管理模块监听异步任务是否满足条件,如果满足条件就会将对应的任务放入callback queue中

4.主线程同步任务执行完成后通过event loop(事件轮询机制)询问callback queue

  • 有可执行的回调函数,就将回调函数放入主线程中执行

  • 如果没有待会再来询问

6.Web Workers:(需要开启服务器)

(1)提供了js分线程实现

(2)相关API:

  • Worker:构造函数,加载分线程执行的js文件

  • Worker.prototype.onmessage:用于接收另一个线程的回调函数

  • Worker.prototype.postMessage:向另一个线程发送信息

(3)不足:

  • 不能操作DOM(不能更新UI)

  • 不能跨域加载JS

  • 不是每一个浏览器都支持这个新特性

(4)代码:

在主线程html中编写

 1 <input type="text" id="number" value="30">
 2 <button id="btn">计算斐波那契数</button>
 3 <script type="text/javascript">
 4 
 5 
 6 
 7 document.getElementById("btn").onclick = function(){
 8   var value = document.getElementById("number").value;
 9 
10   //获得分线程
11   var worker = new Worker("./work.js");
12 
13   //发送给分线程数据
14   worker.postMessage(value);
15   //接收分线程数据
16   worker.onmessage = function(event){
17     console.log(event.data);
18   }
19 
20 }
21 </script>

在同一级目录下work.js

 1 function fibonacci(num){
 2     return num > 2 ? fibonacci(num - 1) + fibonacci(num - 2) : 1;
 3 }
 4 
 5 var onmessage = function(event){
 6     console.log("分线程监视....");
 7 
 8     //获取主线程发送过来的数据
 9     var data = event.data;
10 
11     //分线程处理数据
12     data = fibonacci(data);
13 
14     //返回数据给主线程
15     postMessage(data);
16 };

执行结果:

  不会卡住主进程界面,大批量计算在分线程中执行。

 

posted @ 2019-12-08 16:03  All_just_for_fun  阅读(1131)  评论(0编辑  收藏  举报