五、JS单线程运行原理与多线程

一、进程与线程

	
	进程:正在执行的程序为一个进程。
		 程序的一次运行,它会占用一片独立的内存空间。称为进程
	
	线程:线程是进程内一个独立的执行单元。

		
	1、一个进程中至少一个运行的线程,称为主线程。进程启动后自动创建。
	2、应用程序的代码必须运行线程中。
	
	3、在一个进程内同时有多个线程运行。	
	4、线程池(Thread pool):保存多个线程对象的容器,实现线程对象的反复使用。
	  	
1.1 单线程与多线程区别

在一个进程内至少有一个线程运行,也可以同时有多个线程运行。

		
		多线程:
			优点:能有效提高CPU的利用率
		
			缺点:1、线程并发问题
			     2、线程切换、线程创建的时间开销	
		
		单线程:
			优点:顺序编码比较简单
			缺点: 效率低
	
					
1.2 浏览器是单进程还是多进程?

	浏览器是单进程运行还是多进程运行?
			1、有的是单进程:火狐、老版IE
			2、有的是多进程:谷歌、新版IE
						

>>>>>> 查看应用程序是多进程还是单进程

在这里插入图片描述

JS是单线程运行。
但是使用H5中的Web Workers可以多线程运行。

二、浏览器内核

浏览器内核:支持浏览器运行的最核心的程序。

2.1 浏览器内核
	
	不同浏览器的内核可能不一样:
			Chrome、Safari:webkit内核
			firefox:Gecko
			IE:Trident
			360、国内其他浏览器:Trident+webkit
			

2.2 浏览器内核模块组成部分

	内核有很多模块组成
			主线程:
					1、js引擎模块:负责js的编译与运行
					2、html、css文档解析模块:负责页面文本的解析
					3DOMCSS模块:负责dom、css在内存中的处理,解析为DOM4、布局和渲染模块:参照DOM中对象,负责页面的布局和渲染
	
			分线程:
					1、定时器管理模块:负责定时器的管理
					2DOM事件管理模块:负责事件的管理
					3、Ajax管理模块:负责ajax请求


三、事件循环模型(JS单线程运行原理)

3.1 定时器
	
	1、定时器真的是定时执行的么?
			定时器并不是真正的定时执行。一般会延时一丁点时间运行。
			
	2、定时器回调函数是哪一个线程在执行?
			在主线程中执行的,	js是单线程的。
	
	3、定时器是如何实现的?
			事件循环模型
			
1)JS是单线程执行的
	
	1、我们将代码分为初始化代码和回调代码。
					初始化代码就是主函数代码,包括绑定事件、开启定时任务等。
					回调代码指回调函数。
	
	2JS引擎执行代码流程:
			1) 先执行初始化代码,即主函数代码(包含设置定时器、绑定监听、Ajax调用等)
			2) 在初始化代码执行完毕后,后面在某个时刻才会触发回调函数。
	
	

	3JS是单线程运行,只在主线程执行。
			1) JS是单线程运行,但是浏览器是多线程运行。
			
	   		2) JS引擎执行主函数代码,会将回调函数交给浏览器的事件模块处理。
			   当回调函数被触发时,浏览器事件模块会将回调函数放入到队列中等待执行。
			   当主函数代码执行完毕后,JS引擎会从队列中取出回调函数在栈中执行。
					

>>>>>> 证明js是单线程运行
		alert("xx")  // 暂停当前主线程的运行,同时暂停计时
					 // 点击确定后,恢复程序执行和计时
		
	如下案例,
		先会执行alert("main"),不点击弹窗确定,则延时函数一直不会执行。
		点击弹窗确定后,延时函数才会恢复计时执行。
        console.log("123")

        setTimeout(function(){
            alert("123")
        },0);

        alert("main")

在这里插入图片描述

>>>>>> JS为什么设置为单线程执行,而不是多线程执行
	
	作为浏览器脚本语言,JS的主要用途就是与用户交互,以及操作DOM。
	这决定了它只能是单线程。如果设置为多线程,就会带来很复杂的同步问题。
	
3.2 事件循环模型(JS单线程运行原理)
	
	+++ 事件循环模型由两部分组成
			1、事件管理模块(定时器/DOM事件/Ajax管理模块)
			2、回调队列
	

	+++ 流程		
			1、执行初始化代码,将绑定的回调函数交给事件管理模块管理
			
						1) 定时器回调函数交给定时器管理模块
						2) DOM事件回调函数交给DOM事件管理模块
						3) Ajax回调函数交给Ajax事件管理模块

			2、事件执行时,管理模块会将回调函数添加到队列中
			3、只有当初始化代码执行完毕后(可能要一定的时间),JS引擎才会从任务队列中循环取出回调函数放入执行栈中执行。
	
		    【事件循环模型处理流程指的是定时函数、事件绑定函数、Ajax的执行流程】


>>>>>> JS运行流程

在这里插入图片描述

	
	1JS引擎执行主函数代码,在stack中执行,即在执行上下文栈执行。
	   由于JS是单线程,所以只有一个执行上下文栈。
	   
	2JS引擎执行主代码,将绑定的回调函数交给事件管理模块管理。			
			事件管理模块主要包括:定时器管理模块、事件管理模块、Ajax管理模块
	
	
	3、当回调函数被触发时,事件管理模块会将回调函数放入到队列中等待执行。
	4、当主函数代码执行完毕,JS引擎会从任务队列中取出回调函数放入到栈中执行(一个接一个)
			
3.3 JS线程
	
	1JS是单线程执行的。回调函数也是在主线程执行。
	2H5提出了多线程方案:Web Workers
	3、只能在主线程更新界面,即操作DOM

三、Web Workers

	
	H5规范提供了JS分线程的实现,取名为Web Worksers
	
	相关API
			Worker:构造函数,加载分线程执行的js文件
			Worker.prototype.postMeaasge:开启线程,并另外一个线程发送信息
			Worker.prototype.onmessage:用于接收另一个线程的回调函数
	
	不足:
			Worker内代码不能操作DOM,即Worker内代码看不到window对象。
			
			不能跨域加载JS
			不是每个浏览器都支持分线程。
			
>>>>>> index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script type="text/javascript" src="a.js" ></script>
    
    <script>

        function show(){
        	
        	//加载线程JS文件
            var worker=new Worker("a.js");

            //绑定接收分线程的数据的监听
            worker.onmessage=function(event){
                console.log("主线程接收数据:"+event.data)
            }

            
            //向分线程发送数据
            worker.postMessage(123);
        }
            

    </script>


</head>
<body>

    <button onclick="show()">点击</button>

    
</body>
</html>
>>>>>> a.js

Worker内代码看不到window对象,所以不能操作DOM


function  tt(){
    console.log("123")
}


var onmessage=function(event){

    console.log("分线程接收数据:"+event.data);
    tt();

    //向主线程发送数据
    postMessage("111")
}
>>>>>> 测试

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值