js运行机制解析

js运行机制

JavaScript是单线程

这重设计避免了一个线程在DOM节点上添加内容,另一个线程删除了这个节点的尴尬事件。

任务列队

主线程执行“同步任务”,被主线程挂载起来的是“异步任务”,后者一般是放在一个叫“任务队列”的数据结构中。

JavaScript的运行机制
(1)所有同步任务都在主线程上执行,形成一个执行栈。
(2)主线程之外,还有一个“任务队列”,只要异步任务有了运行结果,就在“任务队列”之中放置一个事件。
(3)一旦“执行栈”中的所有同步任务执行完毕了,系统就会读取“任务队列”,看看里面有哪些事件,那些对应的异步任务,预示结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的三步。(事件循环)。

parse markup and set up DOM(解析标记并设置DOM)
check for event at head of queue(检查队列头部的事件)


事件和回调函数

其实任务列队就是一个事件列队,因为一般我们绑定一个事件,比如点击事件,都是在某个时刻才触发的,这个时候就得放到任务队列里面,等待执行,而在某个DOM节点上绑定了事件,就要有相应的回调函数。
所谓回调函数就是那些被挂载起来,等待执行的代码,才会执行任务队列里的异步任务,一般是按照队列的“先进先出”顺序执行,但是因为存在定时器,所以主线程要检查执行时间,只有到了规定的时间,才能返回主线程。

定时器

setTimeout作为BOM API,它负责设定一个计时器,到点把要执行的函数添加到任务队列,它不能保证立即执行,什么时候执行取决与事件循环什么时候把这个函数调度到主线程。这就是setTimeout不能精确定时执行的原因。

//代码1
console.log('先执行这里');
setTimeout(() => {
    console.log('执行啦')
},0);

setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,意思就是不用再等多少秒了,只要主线程执行栈内的同步任务全部执行完成,栈为空就马上执行。
即便主线程为空,0毫秒实际上也是达不到的。根据HTML的标准,最低是4毫秒。

任务队列包含宏任务以及微任务
  • 宏任务(macrotask):

script(整体代码)、setTimeout、setInterval、UI 渲染、 I/O、postMessage、 MessageChannel、setImmediate(Node.js 环境)

  • 微任务(microtask):

Promise、 MutaionObserver、process.nextTick(Node.js环境)

事件循环
  1. 整体script作为第一个宏任务进入主线程,将遇到的宏任务分到宏任务Event Queue中,将遇到的微任务分到微任务Event Queue中。结束第一轮宏任务结束。
  2. 将微任务中的任务执行完毕后,第一轮事件循环结束。
  3. 第二轮就是执行宏任务,继续将里面的宏任务和微任务剥离来放入各自的列队中,依次循环。

image.png

			setTimeout(function() {
				console.log(1);

				setTimeout(function() {
					console.log(6);
				}, 0);

				new Promise(function(a, b) {
					console.log(7);
					for (var i = 0; i < 10; i++) {
						i == 9 && a();
					}
					console.log(8)
				}).then(function() {
					console.log(9)
				});
			}, 0);
			new Promise(function(a, b) {
				console.log(2);
				for (var i = 0; i < 10; i++) {
					i == 9 && a();
				}
				console.log(3)
			}).then(function() {
				console.log(4)
			});
			console.log(5);

结果是2,3,5,4,1,7,8,9,6

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值