JavaScript语言是一门“单线程”的语言,是逐行往下执行代码的,就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个任务和流程。
1. 同步任务
同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
const num1 = 1;
const num2 = 2;
const num3 = 3;
console.log(num1); // 1
console.log(num2); // 2
console.log(num3); // 3
从上往下一行一行执行。
2. 异步任务
不会进入主线程,所有的异步任务都会进入"任务队列"里,只有所有的同步任务执行完毕后,"任务队列"里的异步任务开始进入主线程执行栈中执行;最基础的异步是setTimeout和setInterval函数。
console.log(1);
setTimeout(() => {
console.log(2);
}, 0)
console.log(3);
结果为: 1 3 2
3. 宏任务、微任务
实际上异步任务之间并不相同,因此他们之间也有优先级之分,所以任务队列被分成两种类型: 宏任务和微任务。
宏任务:
setTimeout
setInterval
Ajax
DOM事件
I/O
script标签中的整体代码
微任务:
new Promise()
new MutaionObserver()
下面我们看一个例子,然后我们根据结果再解释就会有种恍然大明白的感觉了:
console.log(1);
Promise.resolve(2).then(res => {
console.log(2);
})
setTimeout(() => {
console.log(3)
}, 0)
Promise.resolve(4).then(res => {
console.log(4)
})
console.log(5);
setTimeout(() => {
console.log(7)
}, 0)
结果为: 1 5 2 4 3 7
为什么结果不是1 5 2 3 4 7呢?
其实上面的所有内容其实都围绕一个执行机制——事件循环机制(event loop)
*** 4. 事件循环机制(event loop)
js引擎会从上到下逐行进行解析;
将其中的同步任务按照执行顺序排列到执行栈中,所有的异步任务会放到"任务队列"中;
在所有的同步任务执行结束后,在确保没有同步任务的时候,然后检查"任务队列"中是否有任务,如果有,就将第一个事件对应的回调,推到执行栈中执行;
==注意:==异步任务分宏任务和微任务两种类型,微任务比宏任务的执行时间要早,所以会优先把所有的微任务放到执行栈中执行。在执行任何一个宏任务以前(不是队列,是一个宏任务),都会查看微任务队列是否有任务需要清空,也就是宏任务执行以前,必须保证微任务是空的。
所以从上面的代码例子中可以得出:
先把同步任务执行,得到 1,5, 然后依次执行微任务(Promise),得到 2, 4,最后执行宏任务(setTimeout),得到3, 7。所以得出1 5 2 4 3 7
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。