宏任务微任务
微任务: promise.then ,MutationObserver,process.nextTick
宏任务:script ,ajax , 事件,requestAnimationFrame, setTimeout ,setInterval ,setImmediate (ie下),MessageChannel ,I/O ,UI rendering。
微任务 会比宏任务快,js中会先执行script脚
浏览器
- 线程、进程。 计算机调度任务的最小单位是进程。
- js是单线程的 指的是进程中只有一个主线程,指的是主线程执行是单线程的 如果在其中调用了像ajax、setTimeout会再开辟一条线程
- 渲染线程(样式)和js线程是互斥的
- script脚本执行 (宏任务)
- 异步代码需要等待同步代码执行完毕
- 宏任务:script,ajax,事件 微任务: promise.then
当主线程全部执行完毕后 清空微任务 会取出一个宏任务,放到主线程中 => 执行完毕 继续清空微任务 => 无线循环
1) 顺序问题
1 | setTimeout(() => { |
这里面根本走不到异步代码,什么时候走呢,当整个主线程执行完毕之后 浏览器会开辟一条单独的线程去扫描②中的方法有没有好(click点击会产生函数、定时器时间到达会产生函数、ajax返回结果会产生函数),时间一到就会放到③队列中,比如当定时器第一个成功了会放到宏队列中
示例:
1 | setTimeout(() => { |
按照执行顺序 谁先到时间 谁先放到队列中 打印结果 1 2
当主站代码执行完毕之后 取出第一个宏任务放到主站(①)里执行,执行完之后 在取第二个宏任务,放到主站中,一个一个取。
示例:
1 | setTimeout(() => { |
2) 微任务和宏任务执行顺序问题
1 | console.log(1); |
当代码执行的时候会有宏任务和微任务,遇到微任务时会将微任务直接放到微任务队列,当主站代码执行完毕之后,会将微任务队列中的代码全部清空,再取出一个宏任务放到主线程执行
1 | setTimeout(() => { |
当前主栈全部执行完毕后 清空微任务 ,会取出一个宏任务 -> 执行完毕后 继续清空微任务 -> 无线循环
1 | // vue 为什么要提供一个 $nextTick 不是每次一改数据就更新视图 会做一个缓存机制把多次更改缓存到一起,一起刷新视图 |
示例
1 | async function async1(){ |
Nodejs
浏览器事件环是V8引擎提供的, 新版本node11和浏览器基本一样,node里是自己实现的事件环
node中的事件环
1 | ┌───────────────────────┐ |
示例
1)
node中 setImmediate 相当于没有设置时间的setTimeout 不过它们执行的时间段不同
根据调用的上下文
1 | setTimeout(() => { |
它们的执行顺序受node的性能影响 因为有可能主站执行完成后 setTimeout的时间还没到 则会先执行setImmediate
2)
1 | let fs = require('fs'); |
3)
1 |
|