常见的异步操作
- timer
- Ajax
- DOM的事件操作
- Promise.then
- Node读取文件
javascript执行过程
-
从上到下依次解释每一条js语句
-
若是同步任务,则压入一个栈(主线程);如果是异步任务,就放到一个任务队列里
-
开始执行栈里的同步任务,直到将栈里的所有任务都走完,此时栈清空了
-
回过头看异步队列里如果有异步任务完成了,就生成一个事件并注册回调,压入栈中
-
再返回第3步,直到异步队列都清空,程序运行结束
-
宏任务任务对垒和微任务任务队列外层有个事件环,将触发后事件压入栈中执行
示例
setTimeout(function () {
console.log(1);
Promise.resolve().then(function () {
console.log(2);
});
});
setTimeout(function () {
console.log(3);
});
Promise.resolve().then(function () {
console.log(4);
});
console.log(5);
示例注解
-
结果 5,4,1,2,3
-
不妨我们试着分析一下为什么是这个结果,首先输出5,因为console.log(5)是同步代码,这没什么可说的。
之后将前两个setTimeout和最后一个Promise放入异步队列,注意它们的区分,此时执行完了同步代码之后发现微任务和宏任务队列中都有代码,按浏览器的事件环机制,优先执行微任务,此时输出4。
然后执行宏任务队列里的第一个setTimeout,输出1。
此时,setTimeout中又有一个Promise,放入微任务队列。
再次清空微任务队列,输出2。
最后宏任务队列里还有最后一个setTimeout,输出3。
Node和浏览器区别
- 浏览器事件环是运行完一个宏任务马上清空微任务队列。
- Node事件环是清空完一个阶段的宏任务队列之后再清空微任务队列。
常见的宏任务和微任务
| 宏任务 | 微任务 |
|---|---|
| setTimeout | Promise的then方法 |
| setInterval | process.nextTick |
| setImmediate | MutationObserver |
| MessageChannel |