Javascript 是单线程的,所有任务都是同步的,即所有操作需要排队完成,这条队伍叫做主线程。事件循环分为浏览器事件缓存和 nodejs 事件缓存,主要是为了让 JavaScript 代码在运行过程不会阻塞的一种机制。
浏览器的事件循环又分为同步任务和异步任务。
同步任务即主线程上的任务。
异步任务分为宏任务和微任务,在任务队列中:
宏任务 | 微任务 | |
---|---|---|
谁发起 | 宿主(Node,浏览器) | js引擎 |
具体事件 | 1.script 标签内部代码 2.setTimeout/setInterval 3.ajax请求 4.事件绑定 | 1.Promise的then,catch ,finally (但是then 前面的内容为同步) |
任务进行顺序: 同步任务 --> 微任务 --> 宏任务
例题1:
<script>
console.log(1);
setTimeout(function(){
console.log(2)
},0)
new Promise((resolve,reject)=>{
console.log(3)
resolve()
console.log(4)
}).then(()=>{
console.log(5)
})
console.log(6)
</script>
例题2:
async function async1 () {
console.log('async1 start')
await async2();
console.log('async1 end')
}
async function async2 () {
console.log('async2')
}
console.log('script start')
setTimeout(function () {
console.log('setTimeout')
}, 0)
async1();
new Promise (function (resolve) {
console.log('promise1')
resolve();
}).then (function () {
console.log('promise2')
})
console.log('script end')
async1() 是同步任务,等到 await async2() 时,是异步,它后面的语句则是 .then 执行的语句,所以打印async1 end 会放到微任务中。
例题3:
setTimeout(function(){
console.log('1');
});
new Promise(function(resolve){
console.log('2');
resolve();
}).then(function(){
console.log('3');
});
console.log('4');
例题4:
setTimeout(()=>{
new Promise(resolve =>{
resolve();
}).then(()=>{
console.log('test');
});
console.log(4);
});
new Promise(resolve => {
resolve();
console.log(1)
}).then( () => {
console.log(3);
Promise.resolve().then(() => {
console.log('before timeout');
}).then(() => {
Promise.resolve().then(() => {
console.log('also before timeout')
})
})
})
console.log(2);