前端小白理解JS运行机制

JavaScript基本理解

首先,javascript是一门单线程语言,浏览器只分配给js一个主线程,每次只能执行一个任务,但是如果某些执行的任务所需时间过长,等待该任务执行完毕再执行下一任务,无疑需要耗费太多的时间。于是在主线程之外,还有一个任务队列,用于存放相对耗时的任务,等待主线程空闲时执行。

事件循环event loop

根据以上原理,我们可以将任务分为两类:同步任务和异步任务。同步任务是运行在主线程上,一个接一个运行,异步任务则是不在主线程内,进入任务队列的任务。任务队列是一个先进先出的数据结构,先进入任务队列的任务也会先被主任务读取。当主线程的同步任务执行完成,任务队列的第一个任务自动进入主线程。整个任务执行的流程如下:
1、主线程执行同步任务,异步任务等待完成后进入任务队列
2、同步任务执行完毕,主线程读取任务队列中的异步任务
3、重复以上步骤

macrotask与microtask

异步任务还可以划分为这两种类型:macrotask(宏任务)与microtask(微任务)。宏任务包括整体代码script,setTimeout,setInterval,微任务包括Promise,process.nextTick(callback)。

console.log("1");
setTimeout(function(){
	console.log("2")
},500);
console.log("3");
new Promise((resolve) => {
	console.log("4");
	resolve();
}).then(() => {
	console.log("5"); // callback
})
console.log("6");

以上代码在控制台的打印顺序为:1,3,4,6,5,2 . 首先1为同步任务,主线程直接执行,接着遇到了定时器,0.5s后将其回调函数分发至宏任务的任务队列,等待下一次循环调用。再接着执行同步任务打印3,遇到了promise函数,立即执行打印4,其回调函数分发到微任务队列。接着打印6,第一个宏任务就执行完毕了,开始执行微任务,打印5,此时第一轮事件循环结束,开始第二轮,执行之前被分发到宏任务的定时器回调函数,打印2。
按照这么一个顺序,我们不难得出结论:
1、执行第一个宏任务;
2、遇到微任务将其添加至微任务的任务队列中;
3、宏任务执行完毕后,从微任务的任务队列中依次执行微任务;
4、微任务执行完毕后,开始执行第二轮宏任务

需要注意的是,process.nextTick与setTimeout回调函数相比优先级较高。

setTimeout

在开发过程中我们经常需要开启setTimeout定时器用于异步执行任务,但是setTimeout的使用也是需要注意的。
有些时候,我们写了一段setTImeout定时器代码:

setTimeout(function(){
	console.log("setTimeout");
},3000);

按照大部分人的理解,上面的代码将在3s后打印出"setTimeout",但是这是不一定的,有的时候你会发现执行打印的时间延迟了不只3s,这就要谈到setTimeout的执行机制了。
首先,虽然js是单线程的,但浏览器的渲染是多线程的,当浏览器遇到setTimeout函数时,将其放至定时触发器线程,开始计数,当计数到3s时,打印事件进入到任务队列,等待被执行。这时候,如果主线程的任务还在执行,任务队列的任务就会继续等待。当主线程的任务执行完毕,任务队列的任务才开始进入到主线程中,开始执行。所以setTimeout的真正含义是,在指定的延时后,指定某个任务在主线程最早可得的空闲时间执行,只要主线程执行栈的同步任务执行完成,栈为空就会按照顺序执行任务队列中的异步任务。

暂时先写这么多,后续再补充~~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值