js是一门单线程脚本语言,所以需要异步来辅助
异步和同步的区别:
- 异步不会阻塞程序的执行,
- 同步会阻塞程序的执行
事件循环
js在执行时同步和异步任务分别进入不同的执行“场所”,同步进入主线程,异步进入任务队列里。主线程内的任务执行完毕为空,就去任务队列(Event Queue)读取对应的函数,进入主线程执行 这种过程会不断重复,也就是常说的Event Loop(事件循环)。
主线程执行完毕后就是读取任务列表的任务 它分为 宏任务和微任务
什么是宏任务和微任务
宏任务包括:setTimeout setInterval Ajax DOM事件
微任务:Promise async/await
微任务比宏任务的执行时间要早
执行顺序
1.主线程上宏任务、微任务执行顺序
console.log('---start---');//第一轮主线程
setTimeout(() => {
console.log('setTimeout'); // 将回调代码放入个宏任务队列,第二轮宏任务执行
}, 0);
new Promise((resolve, reject) => {
console.log('---Promise第一轮微任务同步执行---');//第一轮微任务同步执行
resolve()
}).then(()=>{
console.log('Promise.then实例成功回调执行'); // 将回调代码放入微任务队列,第一轮宏任务执行完后立即执行
});
console.log('---end---');//第一轮主线程结束
执行顺序:主线程 >> 主线程上创建的微任务 >> 主线程上创建的宏任务
2.宏任务中包含微任务
// 宏任务队列 1
setTimeout(() => {
// 宏任务队列 2.1
console.log('timer_1');
setTimeout(() => {
// 宏任务队列 3
console.log('timer_3')
}, 0)
new Promise(resolve => {
resolve()
console.log('new promise')
}).then(() => {
// 微任务队列 1
console.log('promise then')
})
}, 0)
setTimeout(() => {
// 宏任务队列 2.2
console.log('timer_2')
}, 0)
console.log('========== Sync queue ==========')
执行顺序:主线程 >> 主线程上的宏任务队列1 >> 宏任务队列1中创建的微任务
========== Sync queue ==========
1 timer_1
2 new promise
3 promise then
4 timer_2
5 timer_3