参考https://juejin.cn/post/6844904079353708557
1、主任务队列和等待任务队列
浏览器是多线程的,js是单线程的,
js实现异步处理机制主要依赖浏览器的任务队列
任务队列分为主任务队列和等待任务队列。
在主任务队列自上而下执行的时候,如果遇到一个异步操作任务,不会立即执行而是把它放到等待任务队列中去排队,等待所有的主栈中的主任务队列执行完全后,再执行等待任务队列。
2、宏任务和微任务
异步编程里面又分为宏任务和微任务
宏任务有定时器、事件绑定、ajax、回调函数、node中fs模块
微任务有promise、async await、process.nextTick
执行顺序:先执行主任务,执行完接着执行微任务,最后执行宏任务,按照条件的顺序依次执行。
这种循环机制又叫事件循环(event loop)
这里只写一写简单的总结
起因: js代码的执行过程中,除了依靠函数调用栈来搞定函数的执行顺序外,还依靠任务队列来搞定另外一写代码的执行,整个执行过程中,成为事件循环。
任务队列分为 宏任务 和 微任务。
宏任务大概包括:
- script(整体代码)
- setTimeout
- setInterval
- setImmediate
- I/O
- UI render
微任务大概包括:
- process.nextTick
- Promise(但是new Promise()构造函数中的代码是同步代码,并不是微任务)
- Async/Await(实际就是promise)
- MutationObserver(html5新特性)
在执行宏任务,然后执行该宏任务产生的微任务,若微任务在执行的过程中产生了新的微任务,则继续执行微任务,微任务执行完毕后,再回到宏任务中进行下一轮循环。
console.log(1); setTimeout(() => { console.log(2); process.nextTick(() => { console.log(3); }); new Promise((resolve) => { console.log(4); resolve(); }).then(() => { console.log(5); }); }); new Promise((resolve) => { console.log(7); resolve(); }).then(() => { console.log(8); }); process.nextTick(() => { console.log(6); }); setTimeout(() => { console.log(9); process.nextTick(() => { console.log(10); }); new Promise((resolve) => { console.log(11); resolve(); }).then(() => { console.log(12); }); }); // 1 7 6 8 2 4 3 5 9 11 10 12
浏览器升级后优化了await 使得await变得更快了,直接把await 后面的代码注册为一个微任务。