JS 微任务宏任务执行顺序
console.log('task start')
setTimeout(()=>{
console.log('setTimeout1')
},0)
new Promise((resolve, reject)=>{
console.log('new Promise1')
resolve()
}).then(()=>{
console.log('Promise.then1')
setTimeout(()=>{
console.log('setTimeout2')
},0)
new Promise((resolve, reject)=>{
console.log('new Promise2')
resolve()
}).then(()=>{
console.log('Promise.then2')
})
})
console.log('task end')
// 'task start'
// 'new Promise1'
// 'task end'
// 'Promise.then1'
// 'new Promise2'
// 'Promise.then2'
// 'setTimeout1'
// 'setTimeout2'
我的理解:在执行微队列 microtask queue 中任务的时候,如果又产生了 microtask,那么会继续添加到队列的末尾,也会在这个周期执行,直到 microtask queue 为空停止
在宏任务中添加宏任务和微任务
console.log('task start')
setTimeout(()=>{
console.log('setTimeout1')
setTimeout(()=>{
console.log('setTimeout2')
},0)
new Promise((resolve, reject)=>{
console.log('new Promise2')
resolve()
}).then(()=>{
console.log('Promise.then2')
})
},0)
new Promise((resolve, reject)=>{
console.log('new Promise1')
resolve()
}).then(()=>{
console.log('Promise.then1')
})
console.log('task end')
// 'task start'
// 'new Promise1'
// 'task end'
// 'Promise.then1'
// 'setTimeout1'
// 'new Promise2'
// 'Promise.then2'
// 'setTimeout2'
我的理解:宏任务执行的时候微任务队列已经执行完成了,里面产生的微任务宏任务只能进入下一个事件循环
async
async function asycn1() {
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2')
}
console.log('script start')
setTimeout(() => {
console.log('setTimeout')
}, 0)
asycn1()
new Promise((resolve) => {
console.log('promise1')
resolve()
}).then(() => {
console.log('promise2')
})
console.log('script end')
// 'script start'
// 'async1 start'
// 'async2'
// 'promise1'
// 'script end'
// 'async1 end'
// 'promise2'
// 'setTimeout'
$nextTick(默认走微任务)
mounted() {
this.message = 'aaa' // 此时已经生成 vue 内部维护的异步队列
setTimeout(() => { console.log('222') })
Promise.resolve().then(res => { console.log('333') })
this.$nextTick(() => { // 此时只是将回调函数 push 到上面的那个异步队列
console.log('444')
})
Promise.resolve().then(res => { console.log('555') })
}
// 444 --> 333 --> 555 --> 222
问题
浏览器默认执行顺序 微任务 --> dom 更新 --> 宏任务,那么 vue 使用微任务 nextTick 之后我们为什么能获得更新后的 dom 呢?
export function queueWatcher (watcher: Watcher) { // set 方法后 watcher update 时候触发
const id = watcher.id
if (has[id] == null) {
has[id] = true
if (!flushing) {
queue.push(watcher)
} else {
// if already flushing, splice the watcher based on its id
// if already past its id, it will be run next immediately.
let i = queue.length - 1
while (i > index && queue[i].id > watcher.id) {
i--
}
queue.splice(i + 1, 0, watcher)
}
// queue the flush
if (!waiting) {
waiting = true
if (process.env.NODE_ENV !== 'production' && !config.async) {
flushSchedulerQueue()
return
}
nextTick(flushSchedulerQueue)
// 个函数是微任务还是宏任务,其实都无所谓,甚至同步异步都无所谓。只要我们要操作 DOM 的回调函数放在数据变更之后就可以
}
}
}
所以以下情况是得不到变更后的 DOM
的
Vue.nextTick(()=>{
console.log(document.querySelector('h1').innerText)
})
this.msg = 'hello'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
下一篇: TypeScript 常见问题
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论