自我理解js执行顺序——附件练习题和自我解析的答案

js执行顺序

我们知道,js是一条流水线,没有多余的分支,而且是从上往下执行
原理是v8引擎是用来解析js的,因为v8引擎是单线程所以导致js也是单线程的,

此时你会有疑问:但是我们所认识的定时器不是“多线程”吗?实际上定时器是假的‘多线程’。 这个问题留到后面你就知道了

在v8引擎中有主线程任务队列两个,同时执行顺利就是先同后异,先微后宏
当v8引擎解析到异步代码时,比如定时器,就会把异步代码交给相关的模块处理,处理完之后,再交给事件队列中排队,当执行栈有空时,消息队列就把事件交给调用栈执行。

简单理解就是:军人优先
比如在一个打仗的队伍里,有军人和普通人相互穿插着,军人就是同步,普通人就是异步。因为军人优先,所以所有军人会从队伍里出来,排成一队,则这就是主线程,普通人排成一队,则这就是任务队列,当军人依次完成任务不见了,主线程就会空出来,此时普通人中的成年男人(微任务)就站出来,排到主线程中,当成年男人完成任务也依次不见了,那么剩下的人(宏任务)就要占到主线程中。

通过这个故事,估计我们大体可以了解什么是同步,异步,微任务,宏任务,主线程和任务队列。下面通过做题可以加深对js执行顺序有更深的了解。
在做题前,我们先了解一下宏任务,微任务有哪些

微任务

-我所了解的微任务有

  • Promise.then catch finally
  • async…await(他是promise的语法糖)
  • Object.observe
  • MutationObserver

注意:Promise的内容是同步的,他的then catch finally的回调才是异步的

宏任务

-我所了解的宏任务有

  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • UI rendering

练习1

setTimeout(() => console.log(1), 0)
new Promise(res => {
	console.log(2)
	setTimeout(() => console.log(3), 0)
	res()
}).then(() => console.log(4))
console.log(5)

练习1解析:这个代码是混着的,因此我们从上往下先把军人,男人和剩下的人分开出来

同步微任务宏任务
console.log(2)console.log(4)setTimeout(() => console.log(1), 0)
console.log(5)setTimeout(() => console.log(3), 0)

因此我们得出执行顺序就是2.5.4.1.3

练习2

setTimeout(() =>
	 new Promise(res => {
		console.log(6)
		setTimeout(() => console.log(7), 0)
		res()
	 }).then(() => console.log(8))
, 0)
new Promise(res => {
	console.log(2)
	setTimeout(() => console.log(3), 0)
	res()
}).then(() => console.log(4))
console.log(5)

练习2解析:

同步微任务宏任务
console.log(2)console.log(4)setTimeout(() => new Promise(res => {console.log(6) setTimeout(()=> console.log(7), 0) res()}).then(() => console.log(8)), 0)
console.log(5)setTimeout(() => console.log(3), 0)

我们先执行同步:则前三个我们很容易得出答案:2.5.4
此时我们对于宏任务包含微任务会很懵逼
此时在主线程只剩下宏任务,那么我们把宏任务再接着拆解

同步微任务宏任务
console.log(6)console.log(8)setTimeout(() => console.log(3), 0)
--setTimeout(() => console.log(7), 0)

在这个排队中,我们会觉得3为什么会在7前面,你可以只样子理解,当我们执行到宏任务a1的时候,此时他已经从任务队列出来了,到了主线程中,但是执行的时候,发现他们是一家人,里面有同,微,宏三种,因此我们要把他们拆开,但是你拆开宏就要乖乖排到后面,而不能插队
那么我们很自然的得出答案就是2.5.4.6.8.3.7

练习3

console.log("游戏开始",1);
new Promise( (resolve) => {
   console.log("promise",2);
   resolve();
})
.then( () => {
   console.log("then",3);
});
console.log("promise结束",4);
setTimeout( () => {
   console.log("setTimeout",5);
   new Promise( (resolve) => {
       console.log("promise",6);
       resolve();
   })
   .then( () => {
       console.log("then",7);
   });
},0);
new Promise( (resolve) => {
   console.log(promise,8);
   resolve()
})
.then( () => {
   console.log(then,9)
   setTimeout( () => {
       console.log("setTimeout",10);
   },0);
})
console.log("游戏结束",11);

同理,我么接着拆分

同步微任务宏任务
console.log(“游戏开始”,1);console.log(“then”,3);console.log(“setTimeout”,5);new Promise( (resolve) => {console.log(“promise”,6);resolve();}) .then( () => {console.log(“then”,7);});
console.log(“promise”,2);console.log(then,9) setTimeout( () => {console.log(“setTimeout”,10); },0);-----
console.log(“promise结束”,4);----------
console.log(promise,8);----------
console.log(“游戏结束”,11);----------

我们可以得出前6个答案:1,2,4,8,11,3

此时我们执行到了

console.log(then,9)
setTimeout( () => {
   console.log("setTimeout",10);
},0);

接着拆分

同步微任务宏任务
console.log(then,9)-console.log(“setTimeout”,5);new Promise( (resolve) => {console.log(“promise”,6);resolve();}) .then( () => {console.log(“then”,7);});
--setTimeout( () => { console.log(“setTimeout”,10);},0);

同习题2一样,新增的宏任务不能插队
得出接下里答案是 9

此时我们接着拆分宏a1

同步微任务宏任务
console.log(“setTimeout”,5);console.log(“then”,7)-
console.log(“promise”,6);-setTimeout( () => { console.log(“setTimeout”,10);},0);

得出答案5.6.710

最后习题3的答案就是1.2.4.8.11.3.9.5.6.7.10

做完题是不是觉得定时器是假的‘多线程’。

在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荒男

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值