【视频资源已上架哔哩哔哩,关注up主波罗丁的菠萝】
hello大家好,本次分享一下关于JavaScript执行机制的知识点。那么废话不多说,直接上结论,首先我们知道JavaScript是一门单线程语言,决定JavaScript执行顺序的并不是代码顺序,而是event loop顺序。
我们先来讲解一下什么是同步任务,什么是异步任务。同步任务就是按照代码写的顺序一步一步执行下去,而异步代码呢,会先将要执行的代码放入异步队列里,然后执行同步代码,等同步代码全部执行完毕之后,再去异步队列里去查看是否有待执行的代码,如果有的话,就会执行。
用setTimeout演示一下
setTimeout(()=>{
console.log('timeout');
},0);
console.log('11111');
我们先不看执行结果是什么,先把这段代码的event loop顺序安排一下
// 首先进入整体代码
// 接着遇到了setTimout,执行它,把它对应的方法放到异步队列里去,等0ms之后再来执行它
// 接着走,遇到了console.log('11111');执行它,输出1111
// ok同步的执行完了,我去异步队列瞅瞅还有啥
// 异步队列
// 发现了console.log('timeout');,ok执行它就完了
console.log('timeout');
注意一下setTimeout第二个参数,等0ms之后再执行它,0ms之后需要看同步任务是否已经执行完毕,如果同步任务还在执行,那么只好继续等下去直到同步任务执行完毕
比如
// 1000ms后执行
setTimeout(()=>{
console.log('timeout');
},1000);
alert('同步阻塞');
拿着去浏览器里执行一下,会发现只要我不点按钮一直让同步任务阻塞住它就不输出timeout
接下来我们再说一下Promise
let p = new Promise((resolve,reject)=>{
console.log('promise');
resolve();
});
p.then(()=>{
console.log('resolve');
});
console.log('同步');
我们先不看执行结果是什么,先把这段代码的event loop顺序安排一下
// 首先进入整体代码
// 接着遇到了new Promise,执行它,输出console.log('promise')
// 接着走,遇到了promise的then;执行它,把它对应的代码放到异步队列里
// 接着走,遇到了console.log('同步');执行它,输出同步
// ok同步的执行完了,我去异步队列瞅瞅还有啥
// 异步队列
// 发现了console.log('resolve');,ok执行它就完了,输出resolve
console.log('resolve');
那么Promise和setTimeout有什么不同呢,看着都一样啊,咱们也不磨叽直接上结论,在JavaScript除了同步任务和异步任务外,也可以按照宏任务和微任务来区分。宏任务包括整体代码,setTimeout,setInterval,而微任务包括Promise,process.nextTick。process.nextTick是node环境下的我们暂且不说它。宏任务产生的异步代码会放到下次event loop中,而微任务产生的代码会放到本次event loop的末尾处。我们来用一段代码来演示
// 异步-宏任务
setTimeout(()=>{console.log('timeout')},0);
// 同步
let p = new Promise((resolve,reject)=>{
console.log('promise');
resolve();
});
// 异步-微任务
p.then(()=>{
console.log('resolve');
});
// 同步-宏任务
console.log('同步');
那么这个输出的结果是怎样的的呢,我们再来分析一下,这次已经是第三次手把手分析代码了,明白什么意思吗?
// 首先进入整体代码
// 接着遇到了setTimout,执行它,把它对应的方法放到异步队列【宏任务】里去,等0ms之后再来执行它
// 接着遇到了new Promise,执行它,输出console.log('promise')
// 接着走,遇到了promise的then;执行它,把它对应的代码放到异步队列【微任务】里
// 接着走,遇到了console.log('同步');执行它,输出同步
// ok同步的执行完了,我去异步队列瞅瞅还有啥
// 异步队列
// 【Promise微任务】本次event loop
console.log('resolve');
// 【setTimeout宏任务】下一次event loop
console.log('timeout')
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。