JavaScript是单线程,很多人就会误认为既然是单线程的,那不就是从上到下一行一行的执行的嘛,但是事实是这样的吗?下面我们先看个例子吧
console.log(1)
setTimeout(() => {
console.log(2)
}, 100);
console.log(3)
打印出来的结果是什么呢?是1,2,3这样的顺序吗?
我们来看一下结果
为什么会是这样的呢?下面我们详细的介绍一下JavaScript执行的顺序
拿上面的例子来说,setTimeout就是异步操作,在执行到setTimeout时,就会被加入到异步队列,然后接着执行console.log(3),这个时候主线程的执行完毕,会询问异步队列里面是否有需要执行的代码,有异步队列,就会像执行主线程的任务一样,从上往下,遇到异步操作,继续放入异步队列,直到所有的异步操作执行完毕。
注意:异步队列有两种:宏任务(macrotask )和微任务(microtask )
这里只讲JavaScript
宏任务:
- setTimeout
- setInterval
微任务
- Promise.then catch finally(注意:Promise 的本身里面的代码是同步执行的,只有then、catch、finally是异步操作)
下面再举个稍微复杂的例子
setTimeout(() => {
console.log('setTimeout1')
new Promise((resolve,reject)=>{
console.log("promise1")
resolve()
}).then(()=>{
console.log('promis_then1')
})
});
new Promise((resolve,reject)=>{
console.log('promise2')
resolve()
}).then(()=>{
console.log('promis_then2')
setTimeout(() => {
console.log("setTimeout2")
});
})
setTimeout(() => {
console.log('setTimeout3')
});
console.log('4')
正确的结果是:
上面的列子setTimeout没有写延迟时间,默认延迟时间是一样的,其实如果延迟时间不同的话,就是异步队列会根据延迟时间的长短,来调整宏任务的执行顺序。