前置概念:
js是一门单线程语言,代码执行顺序是自上而下的,这一点毫无质疑,但是由于事件循环机制(Event loop)的存在,使得我们视觉上会产生错觉,如以下代码
let a = 0
setTimeout(() => {
a++
}, 0);
function logA() {
console.log(a);
}
logA()
输出结果为0,显然a++的操作我们无法看到,其本质是因为定时器内的代码执行发生在LogAn()之后。
new Promise((resolve,reject)=>{
console.log('1');
resolve()
})
.then(value=>{
console.log('3');
})
console.log('2');
在以上的代码中也存在类似的情况,最终输出结果为1,2,3,promise实例化对象后的then()执行也发生在所有代码之后
小结:
由于事件循环机制的存在,我们的一些特定代码会在主线程结束后才能开始执行,这些代码就是异步代码,在主线程执行的则被称为同步代码
小结:
由于事件循环机制的存在,我们的一些特定代码会在主线程结束后才能开始执行,这些代码就是异步代码,在主线程执行的则被称为同步代码
异步代码中分为两种任务,宏任务和微任务。
- 宏任务:setTimeout setInterval Ajax DOM事件
- 微任务:Promise async/await
图解:
js自上而下执行主线程中的代码时,如果遇到异步代码,将异步代码置在一旁等候,等到主线程代码执行完后再利用事件循环(event loop)和微宏任务的执行队列,决定异步代码是否执行以及它们的执行顺序
执行顺序的规则:
微任务先执行,宏任务在后,同一任务下如果执行发生冲突,则根据代码书写顺序比较先后。如:当定时器和用户点击事件在同一时间触发时