<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          對(duì)微任務(wù)和宏任務(wù)的執(zhí)行順序的理解

          共 4449字,需瀏覽 9分鐘

           ·

          2021-05-08 04:44

          首先給一段例子:

          js 是單線程執(zhí)行的,js中的任務(wù)按順序一個(gè)一個(gè)的執(zhí)行,但是一個(gè)任務(wù)耗時(shí)太長(zhǎng);

          那么后面的任務(wù)就需要等待,為了解決這種情況,將任務(wù)分為了同步任務(wù)和異步任務(wù);

          而異步任務(wù)又可以分為微任務(wù)和宏任務(wù)。

          代碼示例:

          console.log('script start');

          setTimeout(function({
            console.log('setTimeout');
          }, 0);

          Promise.resolve().then(function({
            console.log('promise1');
          }).then(function({
            console.log('promise2');
          });

          console.log('script end'); 

          返回結(jié)果的打印順序是:

          script start
          script end
          promise1
          promise2
          setTimeout

          具體為什么會(huì)打印出這個(gè)順序?

          我們具體看一下js的執(zhí)行流程:

          解讀:

          1)、同步和異步任務(wù)分別進(jìn)入不同的執(zhí)行"場(chǎng)所",同步的進(jìn)入主線程,異步的進(jìn)入Event Table并注冊(cè)函數(shù)

          2)、當(dāng)指定的事情完成時(shí),Event Table會(huì)將這個(gè)函數(shù)移入Event Queue

          3)、主線程內(nèi)的任務(wù)執(zhí)行完畢為空,會(huì)去Event Queue讀取對(duì)應(yīng)的函數(shù),進(jìn)入主線程執(zhí)行。

          4)、上述過(guò)程會(huì)不斷重復(fù),也就是常說(shuō)的Event Loop(事件循環(huán))

          那么主線程內(nèi)的任務(wù)執(zhí)行為空的判定?

          在js引擎中,存在一個(gè)叫monitoring process的進(jìn)程,這個(gè)進(jìn)程會(huì)不斷的檢查主線程的執(zhí)行情況,一旦為空,就會(huì)去Event Quene檢查有哪些待執(zhí)行的函數(shù)。

          宏任務(wù)和微任務(wù)的分類

          宏任務(wù):

          • setTimeout
          • setInterval

          js主代碼

          • setImmediate(Node)
          • requestAnimationFrame(瀏覽器)

          微任務(wù):

          • process.nextTick
          • Promise的then方法

          微任務(wù) 和 宏任務(wù)的執(zhí)行分析

          微任務(wù)和宏任務(wù)的問(wèn)題應(yīng)該是前端面試中比較常見(jiàn)的,他們都從屬于異步任務(wù),主要區(qū)別在于他們的執(zhí)行順序,Event Loop的走向和取值

          這張圖的意思就是:

          • 1)、存在微任務(wù)的話,那么就執(zhí)行所有的微任務(wù)
          • 2)、微任務(wù)都執(zhí)行完之后,執(zhí)行下一個(gè)宏任務(wù)
          • 3)、1, 2以此循環(huán)著 對(duì)于微任務(wù)的執(zhí)行順序上也有些需要注意的地方

          基本上,若你喜歡異步任務(wù)盡可能快地執(zhí)行,那就使用process.nextTick

          根據(jù)語(yǔ)言規(guī)格,Promise對(duì)象的回調(diào)函數(shù),會(huì)進(jìn)入異步任務(wù)里面的”微任務(wù)“(microtask)隊(duì)列。

          微任務(wù)隊(duì)列追加在process.nextTick隊(duì)列的后面。也屬于本輪循環(huán)。所以,下面的代碼總是先輸出3,再輸出4

          process.nextTick(()=>console.log(3))
          promise.resolve().then(()=>console.log(4))
          //輸出為 //3 //4 

          此時(shí)需要注意,只有前一個(gè)隊(duì)列完全清空后,才會(huì)執(zhí)行下一個(gè)隊(duì)列

          process.nextTick(()=>console.log(1))
          promise.resolve().then(()=>console.log(2))
          process.nextTick(()=>console.log(3))
          promise.resolve().then(()=>console.log(4))
          //輸出為 //1 //3 //2 //4 //上面的代碼中,process.nextTick的回調(diào)會(huì)早執(zhí)行于Promise 

          以下是一段多層次的代碼

          • 這時(shí),我們可以通過(guò)以下代碼進(jìn)行一個(gè)微任務(wù)和宏任務(wù)的執(zhí)行順序練習(xí)
          console.log('1');

          setTimeout(function({
              console.log('2');
              process.nextTick(function({
                  console.log('3');
              })
              new Promise(function(resolve{
                  console.log('4');
                  resolve();
              }).then(function({
                  console.log('5')
              })
          })
          process.nextTick(function({
              console.log('6');
          })
          new Promise(function(resolve{
              console.log('7');
              resolve();
          }).then(function({
              console.log('8')
          })

          setTimeout(function({
              console.log('9');
              process.nextTick(function({
                  console.log('10');
              })
              new Promise(function(resolve{
                  console.log('11');
                  resolve();
              }).then(function({
                  console.log('12')
              })
          }) 

          第一輪循環(huán):

          1)、首先打印 1
          2)、接下來(lái)是setTimeout是異步任務(wù)且是宏任務(wù),加入宏任務(wù)暫且記為 setTimeout1
          3)、接下來(lái)是 process 微任務(wù) 加入微任務(wù)隊(duì)列 記為 process1
          4)、接下來(lái)是 new Promise 里面直接 resolve(7) 所以打印 7 后面的then是微任務(wù) 記為 then1
          5)、setTimeout 宏任務(wù) 記為 setTimeout2


          第一輪循環(huán)打印出的是 1 7
          當(dāng)前宏任務(wù)隊(duì)列:setTimeout1, setTimeout2
          當(dāng)前微任務(wù)隊(duì)列:process1, then1,

          第二輪循環(huán):

          1)、執(zhí)行所有微任務(wù)
          2)、執(zhí)行process1,打印出 6
          3)、執(zhí)行then1 打印出8
          4)、微任務(wù)都執(zhí)行結(jié)束了,開始執(zhí)行第一個(gè)宏任務(wù)
          5)、執(zhí)行 setTimeout1 也就是 第 3 - 14 行
          6)、首先打印出 2
          7)、遇到 process 微任務(wù) 記為 process2
          8)、new Promise中resolve 打印出 4
          9)、then 微任務(wù) 記為 then2

          第二輪循環(huán)結(jié)束,當(dāng)前打印出來(lái)的是 1 7 6 8 2 4
          當(dāng)前宏任務(wù)隊(duì)列:setTimeout2
          當(dāng)前微任務(wù)隊(duì)列:process2, then2

          第三輪循環(huán):

          1)、執(zhí)行所有的微任務(wù)
          2)、執(zhí)行 process2 打印出 3
          3)、執(zhí)行 then2 打印出 5
          4)、執(zhí)行第一個(gè)宏任務(wù),也就是執(zhí)行 setTimeout2 對(duì)應(yīng)代碼中的 25 - 36 行
          5)、首先打印出 9
          6)、process 微任務(wù) 記為 process3
          7)、new Promise執(zhí)行resolve 打印出 11
          8)、then 微任務(wù) 記為 then3


          第三輪循環(huán)結(jié)束,當(dāng)前打印順序?yàn)椋? 7 6 8 2 4 3 5 9 11
          當(dāng)前宏任務(wù)隊(duì)列為空
          當(dāng)前微任務(wù)隊(duì)列:process3,then3

          第四輪循環(huán):

          1)、執(zhí)行所有的微任務(wù)
          2)、執(zhí)行process3 打印出 10
          3)、執(zhí)行then3 打印出 12

          代碼執(zhí)行結(jié)束:
          最終打印順序?yàn)椋? 7 6 8 2 4 3 5 9 11 10 12

          原文地址 https://zhuanlan.zhihu.com/p/257069622

          點(diǎn)擊關(guān)注我們↓

          瀏覽 125
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美肏逼视频 | 云盘流出真实操逼免费视频国产 | 暧暖无码| 日本一级黄色电影 | 黄色成人网站在线看 |