一个厨师的角度来谈JS的运行机制

1,097 阅读3分钟

文章是参考西瓜视频“技术蛋老师”的“宏任务微任务”视频来写的

一个菜单

菜单:麻辣鱼头、红烧乳猪蹄、麻婆没豆腐、红烧木耳、凉拌小菜、一碗白米饭、一壶白开水、油焖大虾、糖醋鲤鱼

厨师的念叨

哎呀,这桌菜的顾客还挺会吃,荤素搭配,凉热都有,吃的还挺有味儿。先分一下类吧:现成的(同步任务)、硬菜(宏任务)和素菜(微任务

现成的:白米饭、白开水。但是不能先上白米饭和白开水啊,没有菜怎么行呢,容易挨打啊,我可不能这么干。再看看有啥菜吧?

硬菜:麻辣鱼头、红烧乳猪蹄、油焖大虾、糖醋鲤鱼

素菜:麻婆没豆腐、红烧木耳、凉拌小菜

先把米饭和白开水盛好备用(执行同步任务),接下来炒菜(执行异步任务),硬菜需要时间长,顾客需要等很久,那样体验度不好,先炒凉菜先让客户有的吃(先执行微任务),然后再炒硬菜(后执行宏任务

JS执行机制

主线程从任务队列中读取事件,这个过程是不断循环的,所以整个的这种运行机制又称为Event Loop(事件循环)。Event Loop是JavaScript的执行机制

同步任务和异步任务

同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务

异步任务:不进入主线程,而进入任务队列(task queue) 只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行

同步异步执行流程.png

宏任务和异步任务

宏任务微任务
定时器Promise(async/await)
事件绑定process.nexTick
AjaxMutationObserve
回调函数
Node中fs可以进行异步I/O操作

执行优先级:SYNC>MICRO>MACRO

宏任务和微任务执行流程.png

厨师做菜

    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('白开水')
// 控制台结果
    白米饭
    白开水
    凉拌小菜
    麻婆没豆腐
    红烧木耳
    麻辣鱼头
    红烧乳猪蹄
    油焖大虾
    糖醋鲤鱼

首先,厨师将菜单分类:现成的、硬菜和素菜。

异步任务执行流程1.png

第二:把现成的白米饭和白开水先盛好,放在桌子上(将同步代码放入执行栈中执行,在控制台输出)

异步任务执行流程2.png

第三:清理灶台(清空执行栈),素菜比较好做,依次将素菜先做完(先执行微任务)直至素菜做完(清空微任务队列)上桌

异步任务执行流程3.png

第四:素菜做完了,该做硬菜了(执行宏任务),按照顺序做硬菜(依次执行宏任务队列)

异步任务执行流程4.png

第五:所有硬菜全部做完(清空宏任务队列),至此菜单所列菜都已做完并上桌(一次事件循环结束

异步任务执行流程5.png

到此为止,厨师的这一桌菜做完了。在休息的同时厨师去问一下老板是还有新的顾客点菜,如果有新顾客点菜,再继续按照以上的步骤做菜(再次执行事件循环),完成自己的工作。

参考博客

blog.csdn.net/alokka/arti…

www.cnblogs.com/zwnsyw/p/12…