文章是参考西瓜视频“技术蛋老师”的“宏任务微任务”视频来写的
一个菜单
菜单:麻辣鱼头、红烧乳猪蹄、麻婆没豆腐、红烧木耳、凉拌小菜、一碗白米饭、一壶白开水、油焖大虾、糖醋鲤鱼
厨师的念叨
哎呀,这桌菜的顾客还挺会吃,荤素搭配,凉热都有,吃的还挺有味儿。先分一下类吧:现成的(同步任务)、硬菜(宏任务)和素菜(微任务)
现成的:白米饭、白开水。但是不能先上白米饭和白开水啊,没有菜怎么行呢,容易挨打啊,我可不能这么干。再看看有啥菜吧?
硬菜:麻辣鱼头、红烧乳猪蹄、油焖大虾、糖醋鲤鱼
素菜:麻婆没豆腐、红烧木耳、凉拌小菜
先把米饭和白开水盛好备用(执行同步任务),接下来炒菜(执行异步任务),硬菜需要时间长,顾客需要等很久,那样体验度不好,先炒凉菜先让客户有的吃(先执行微任务),然后再炒硬菜(后执行宏任务)
JS执行机制
主线程从任务队列中读取事件,这个过程是不断循环的,所以整个的这种运行机制又称为Event Loop(事件循环)。Event Loop是JavaScript的执行机制
同步任务和异步任务
同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务
异步任务:不进入主线程,而进入任务队列(task queue) 只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行
宏任务和异步任务
宏任务 | 微任务 |
---|---|
定时器 | Promise(async/await) |
事件绑定 | process.nexTick |
Ajax | MutationObserve |
回调函数 | |
Node中fs可以进行异步I/O操作 |
执行优先级:SYNC>MICRO>MACRO
厨师做菜
console.log('一碗白米饭')
setTimeout(function () {
console.log('麻辣鱼头')
}, 0)
new Promise(function (resolve, reject) {
resolve('凉拌小菜')
}).then(res => {
console.log(res)
})
new Promise(function (resolve, reject) {
resolve('麻婆没豆腐')
}).then(res => {
console.log(res)
})
setTimeout(function () {
console.log('红烧乳猪蹄')
console.log('油焖大虾')
}, 0)
setTimeout(function () {
console.log('糖醋鲤鱼')
}, 0)
new Promise(function (resolve, reject) {
resolve('红烧木耳')
}).then(res => {
console.log(res)
})
console.log('白开水')
// 控制台结果
白米饭
白开水
凉拌小菜
麻婆没豆腐
红烧木耳
麻辣鱼头
红烧乳猪蹄
油焖大虾
糖醋鲤鱼
首先,厨师将菜单分类:现成的、硬菜和素菜。
第二:把现成的白米饭和白开水先盛好,放在桌子上(将同步代码放入执行栈中执行,在控制台输出)
第三:清理灶台(清空执行栈),素菜比较好做,依次将素菜先做完(先执行微任务)直至素菜做完(清空微任务队列)上桌
第四:素菜做完了,该做硬菜了(执行宏任务),按照顺序做硬菜(依次执行宏任务队列)
第五:所有硬菜全部做完(清空宏任务队列),至此菜单所列菜都已做完并上桌(一次事件循环结束)
到此为止,厨师的这一桌菜做完了。在休息的同时厨师去问一下老板是还有新的顾客点菜,如果有新顾客点菜,再继续按照以上的步骤做菜(再次执行事件循环),完成自己的工作。