js执行机制

js为什么是单线程?
从用途出发,假定js有两个线程,一个添加节点,一个删除这个节点,那么js该怎么运行?
这很矛盾,但确实是不得不考虑的问题
而单线程不存在这样的问题,因为它同一时间只能做一件事,然而效率太低了
所以js作为单线程的语言,也要去考虑如何去实现多线程

js多线程的实现取决于它的运行环境,比如浏览器,浏览器是多线程的,即浏览器开辟了几个线程去辅助js线程的执行

浏览器的五个线程:
js主线程:负责执行栈中栈顶代码的执行
GUI 渲染线程:负责render树的渲染(节点与css样式)
事件监听线程:负责监听事件
以上三个为常驻线程
记时线程:定时器
http异步线程

然而子线程依旧由js主线程控制,本质就是这样了,无法改变
单线程中一个任务执行完后才能执行另一个任务
如果前一个任务耗时很长,那后一个任务就不得不等着,为了解决这种问题任务就分为了两种:同步和异步
同步任务即在主线程上,一个任务执行完后再执行另一个任务
异步任务即不进入主线程,是进入任务队列的任务,当任务队列通知主线程某个异步任务可以执行了,该任务才会进入主线程执行

总体来说,只要主线程空了,就会读取任务队列,不断重复,这就是事件循环

以上并非js运行机制的全部,同步和异步只是广义上的,还要两个更细节的东西
宏任务和微任务
微任务会使程序先放入执行栈中执行
宏任务:整体的script,计时器,事件回调,http回调
微任务:Promise和MutationObsever

实例解析js执行机制

	console.log(1);
	console.log(2);
	console.log(3);

打印顺序为123
这是同步任务,按顺序一步一步执行

	console.log(1);
	setTimeout(function () {
		console.log(2);
	},0)
	console.log(3);

打印顺序为132
setTimeout为异步任务,异步任务进入异步队列,需要等到同步任务执行完后才会执行任务队列中的任务,即使时间设定为0ms

	console.log(1);
	setTimeout(function() {
	    console.log(2)
	},0);
	new Promise(function(resolve) {
	    console.log(3);
	    resolve();
	}
	).then(function() {
	    console.log(4)
	});
	console.log(5);

打印顺序为13542
当涉及到宏任务和微任务时,执行机制就是先执行宏任务再执行微任务,然后执行另一个宏任务,不断循环

script整体作为第一个宏任务进入主线程,遇到console.log输出1,遇到setTimeout放到异步队列,遇到Promise直接执行出3,到这里第一个宏任务并未执行完,遇到console.log(5)时输出5,至此第一个宏任务已经执行完了,而后开始执行微任务then输出4,此时微任务也执行完了,开始执行另一个宏任务中的setTimeout输出2

	console.log(1);
	setTimeout(function() {
		new Promise(function(resolve) {
		    console.log(6);
		    resolve();
		}
		).then(function() {
		    console.log(7)
		});
		console.log(2);
	},0);
	new Promise(function(resolve) {
	    console.log(3);
	    resolve();
	}
	).then(function() {
	    console.log(4)
	});
	console.log(5);

这里在上述代码的console.log(2)之前增加了Promise和then
打印顺序为1354627,这里setTimeout内部整体作为宏任务执行,遇到Promise直接输出6,此时宏任务并未执行完,遇到console.log(2)时输出2,至此宏任务结束,执行微任务输出7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值