js执行顺序
Posted 前端小白,请多指教
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js执行顺序相关的知识,希望对你有一定的参考价值。
1.首先js是单线程的
所有的同步任务都是按顺序依次执行的,前面的执行完了之后才会执行后面的任务。遇到计算量大的代码就会阻塞在这里。下面的代码就是打印输出10000次,当循环走完了之后 才会走后面的代码,输出的时间是981ms
输出981ms
2.因为js是单线程的,所有的任务都需要按顺序执行,那如果我在执行过程中开启了一个定时器,定时器延迟10秒执行,后面的代码是不是要十秒之后才执行呢?
测试一下
输出的结果表示:定时器后面的代码先执行了,而定时器里面的代码再10秒后执行了
这是为什么呢?
因为js虽然是单线程,但是我们并不需要所有的代码都要依次执行,避免一些不必要的阻塞。所以就引入了事件循环队列。引入了事件循环队列之后,就将js中所有的代码分成了两大类 ,一类是同步代码,另一类是异步代码。同步代码的执行顺序总是早于异步代码。 可以理解成,js从上到下依次执行,遇到同步的就直接执行,遇到异步的,就将异步的代码放到最后再执行。
下面代码的执行顺序是可以这样理解, 从上到下依次执行。先执行一号代码,是同步的,就直接输出。然后执行到二号代码,是个定时器,定时器是异步的,所以放到最后面再执行。然后执行三号代码,三号是同步的,直接输出。然后执行到四号代码,四号代码也是定时器,是异步的,所以放到最后(这个时候四号的异步代码是在二号的异步代码后面的)。然后执行到五号代码,直接输出。这个时候同步的代码已经全部执行完了,就开始执行刚刚放到最后面的二号代码和四号代码。
所以输出顺序是 同步1,同步2,同步3,异步1,异步2
输出结果
而实际上,就是将异步的代码放入任务队列中去,等同步的代码执行完了之后,然后再去执行任务队列里的任务。
哪些任务会进入任务队列呢(异步任务有哪些)?
定时器,ajax异步请求,promise.then里的东西 等等
任务队列又分成两个,一个是宏任务队列,一个是微任务队列。微任务队列里的任务要优先于宏任务队列里的任务
宏任务:定时器等
微任务:promise.then()里的代码,promise是同步的,ajax异步请求等
上面代码的执行顺序是(结合图一起看):
1.遇到了1号代码,是同步的,直接执行 输出1号,同步1。
2.遇到了二号代码,是个定时器,是宏任务,异步的。所以先不执行,放入宏任务队列
3.遇到三号代码的promise,是个微任务,先不执行,放入微任务队列
4.遇到5号代码,是同步的,直接执行 输出5号,同步2
5.这个时候同步代码执行完了,然后去任务队列里找任务执行。任务队列里有两个队列,一个是宏任务队列,里面有个定时器。还有一个微任务队列,里面有个promse成功的回调。因为微任务执行顺序是先于宏任务的,所以会先执行promise里面的代码
6.执行promise里的代码,遇到三号代码了,是同步的 直接执行 输出3号,微任务1
7.继续向下执行 遇到4号的定时器了,4号定时器是异步的,并且是宏任务,所以先不执行,放入宏任务队列
8.这个时候微任务队列里已经没有任务了,所以去执行宏任务队列里的任务。宏任务队列里先在有两个任务,一个是2号的定时器,一个是4号的定时器。
9.按顺序,先执行2号定时器里面的代码,里面的代码是同步的,直接执行 输出2号,宏任务1
10.执行完宏任务里的第一个任务之后(2号定时器),看一下微任务队列里还有没有任务, 有的话就继续执行微任务队列里的任务,没有的话就继续执行下一个宏任务队列里的任务。
11.我们这里微任务队列已经没有其他任务了,所以继续执行宏任务队列里的任务。执行4号定时器,里面的代码是同步的,所以直接执行,输出 4号,promise里的定时器
输出结果
js的加载顺序
参考技术A 先加载执行a.js,完毕后再加载执行b.js。先执行a.js,完毕后再执行b.js。
这就不可以确定谁先执行了,因为通过创建script标签引入的JS,是谁先加载完毕谁先执行,与创建顺序无关。
对于创建script标签引入JS来讲,在某些高级浏览器中有async属性用于控制是按照加载完毕的顺序执行,还是按照创建顺序执行。
以上是关于js执行顺序的主要内容,如果未能解决你的问题,请参考以下文章