JS的运行机制

本文详细解析了JavaScript的执行机制,包括同步与异步任务处理、宏任务与微任务的区别及执行顺序。通过实例代码展示了不同任务类型的执行流程,帮助读者理解JS运行机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为同步、异步还有宏任务、微任务的的原因,所以JS的程序执行顺序并不是按照代码书写的顺序来的(这是废话...)

那么JS的代码执行顺序到底是怎样的呢?

首先,同步的优先级是大于异步的,在JS程序执行的时候,遇到了异步任务,比如说ajax、setTimeout、setInterval...,JS会将这些异步任务丢到一边。(因为这些任务大部分都是耗时较久的。)

 

在主线程中所有的同步任务执行完毕之后,然后JS会去查看Event Queue,这个Event Queue是就是等待被执行的异步程序的回调函数队列(因为异步程序在被丢到一边的时候可能已经ok了,比如说请求的数据到了、定时器设置的时间到了,他的回调函数可以被执行了。)

所以说JS是先执行主线程中可以被执行的同步程序,然后去执行异步程序。顺带需要注意的是,在异步程序中,setTimeout的优先级是高于ajax的,也就是在主线程任务结束之后,JS会先去问询setTimeout是否可以执行,如果seTimeout还没准备好,才回去问询ajax。

当然,如果JS的运行机制不会这么简单。

另外我们还需要理解的就是“宏任务”和“微任务”。

  • macro-task(宏任务):包括整体代码script,setTimeout,setInterval
  • micro-task(微任务):Promise,process.nextTick

在执行一轮主线程当中的任务时候,先执行的是“宏任务”。执行机制如下图:

异步、同步和宏任务、微任务的运行机制,就决定了JS程序的运行机制。通过一段代码,来理解一下。

		setTimeout(()=>{
			console.log("setTimeout")
		})
		
		new Promise((res,rej)=>{
			console.log("Promise")
			res()
		}).then((res,rej)=>{
			console.log("then")
		})
		
		console.log("script")		

首先,JS解析到了setTimeout,发现这是一个异步程序,把他丢到一边(等待第一轮执行完再去问询它)。然后再下面就遇到了Promise,new Promise立即执行了(注意,虽然Promise是微任务,但是这里是new Promise),输出了“Promise”,然后继续往下,遇到了"then"(process.nextTick),这个是微任务,丢到一边先不管。再往下,遇到了console.log(‘script’),这个毫无疑问是宏任务,所以输出“script”。在回过头来看,这一轮执行完毕之后,主线程里还有一个微任务没有执行,就是consloe.log('then'),所以回过头再输出一个‘then’,然后这一轮主线程是执行完了。去看看异步的Event Queue有没有准备被执行的回调函数(console.log(‘setTimeout’)很伤心,明明我设定的是0秒执行,这么久才来问我.....),好了最后输出“setTimeout”结束。

再来一个复杂一点的,

console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

输出顺序是1、7、6、8、2、4、3、5、9、11、10、12。

微任务里面谁先执行的问题其实可以理解成一个队列,队列就是谁先被丢进Event Queue里面谁就先执行。这个和异步不一样,异步是谁先准备好被执行谁就先被执行回调函数。

关于运行机制还要多多去细心体会,分享这位老哥的博客,分析的很通俗易懂:

https://juejin.im/post/59e85eebf265da430d571f89

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值