1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        JavaScript同步任務與異步任務執(zhí)行順序

        共 2823字,需瀏覽 6分鐘

         ·

        2021-10-13 23:44

        點擊上方藍色字體,選擇“標星公眾號”

        優(yōu)質文章,第一時間送達

        JavaScript是單線程執(zhí)行的,即 js 中任務是按順序依次執(zhí)行的,但若其中一個任務執(zhí)行時間過長,后續(xù)任務會一直等待,造成程序假死。為了解決這個問題,將任務分為同步任務和異步任務,其中異步任務又分為宏任務和微任務。

        同步任務與異步任務:

        同步任務:又叫做非耗時任務,指的是在主線程上排隊執(zhí)行的那些任務

            ? ?只有前一個任務執(zhí)行完畢,才能執(zhí)行后一個任務

        異步任務:又叫做耗時任務,異步任務由JavaScript 委托給宿主環(huán)境進行執(zhí)行?

             當異步任務執(zhí)行完成后,會通知JavaScript 主線程執(zhí)行異步任務的回調函數(shù)

        1. 同步任務由JavaScript主線程次序執(zhí)行

        2. 異步任務委托給宿主環(huán)境執(zhí)行

        3. 已完成的異步任務對應的回調函數(shù),會被加入到任務隊列中等待執(zhí)行

        4. JavaScript 主線程執(zhí)行棧被清空后會讀取任務隊列中的回調函數(shù),次序執(zhí)行

        5. JavaScript 主線程不斷重復上面的第4步

        JavaScript主線程從“任務隊列”中讀取異步任務的回調函數(shù),放到執(zhí)行棧中依次執(zhí)行。這個過程是循環(huán)不斷的,所以整個的這種運行機制又稱為 EventLoop (事件循環(huán))

        宏任務與微任務

        宏任務:異步Ajax請求,setTimeout,setInterval,文件操作,new Promise等

        微任務:Promise.then、.catch、.finally,process.nextTick等

        ?

        宏任務與微任務是交替執(zhí)行的,每次執(zhí)行完宏任務都會檢查是否有微任務

        代碼示例:

        console.log('A');

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

        Promise.resolve().then(function()?{
        ??console.log('C');
        }).then(function()?{
        ??console.log('D');
        });

        console.log('E');

        先執(zhí)行同步任務打印A和E,再執(zhí)行異步任務中的微任務,打印C和D,最后執(zhí)行宏任務打印B

        最終打印結果:AECDB

        可能有人會問,為什么微任務優(yōu)先于宏任務執(zhí)行,其實并不是,這里先執(zhí)行微任務的原因是,script本身也是一個宏任務,這個宏任務執(zhí)行結果就是添加各種微任務與宏任務,比如下面代碼中,同步任務執(zhí)行完成后,會先執(zhí)行script的宏任務,即添加一個setTimeout的宏任務與一個Promise.then的微任務,這個宏任務執(zhí)行完成后,就該執(zhí)行Promise.then的微任務了。并不是微任務優(yōu)先級大于宏任務,而是這個宏任務執(zhí)行感知不強,會讓人感覺并沒有執(zhí)行宏任務,其實是同樣遵循上面流程,執(zhí)行了宏任務

        下面是一個多層次代碼,可進行練習:

        ?1?console.log('1')
        ?2?
        ?3?setTimeout(function?()?{
        ?4???console.log('2')
        ?5???process.nextTick(function?()?{
        ?6?????console.log('3')
        ?7???})
        ?8???new?Promise(function?(resolve)?{
        ?9?????console.log('4')
        10?????resolve()
        11???}).then(function?()?{
        12?????console.log('5')
        13???})
        14?})
        15?Promise.resolve().then(function?()?{
        16???console.log('6')
        17?})
        18?new?Promise(function?(resolve)?{
        19???console.log('7')
        20???resolve()
        21?}).then(function?()?{
        22???console.log('8')
        23?})
        24?
        25?setTimeout(function?()?{
        26???console.log('9')
        27???process.nextTick(function?()?{
        28?????console.log('10')
        29???})
        30???new?Promise(function?(resolve)?{
        31?????console.log('11')
        32?????resolve()
        33???}).then(function?()?{
        34?????console.log('12')
        35???})
        36?})

        分析:

        第一遍:

        1. 首先執(zhí)行第一行的同步任務,打印1

        2. 第三行的setTimeout是異步任務中宏任務,加入宏任務記為setTimeout1

        3. 下面第15行Promise.then是異步任務中的微任務,加入微任務記為 then

        4. 第18行new Promise是同步任務,執(zhí)行第一個log直接打印7,后面的 .then 是微任務,存入微任務中記為 then1

        5. 第25行setTimeout是異步任務中宏任務,加入宏任務記為 setTimeout2

        此時整個程序狀態(tài)如下:

        第二遍:

        1. 首先執(zhí)行微任務區(qū)中的任務,then打印6,then1打印8

        2. 微任務區(qū)任務執(zhí)行完成,再執(zhí)行宏任務區(qū) setTimeout1 ,打印2,將第5行process微任務放入微任務區(qū)記作 process2

        3. 第8行new Promise為同步任務,立即執(zhí)行打印4,將后續(xù) .then 微任務?放入微任務區(qū)記作 then2

        此時整個程序狀態(tài)如下:

        第三遍:

        1. 首先執(zhí)行微任務區(qū),process2,打印3,再執(zhí)行then2,打印5?

        2. 微任務區(qū)執(zhí)行完成,再去執(zhí)行宏任務區(qū)中的setTimeout2,首先是第26行l(wèi)og直接打印9

        3. 將第27行process微任務放入微任務區(qū)記作 process3

        4. 第30行new Promise為同步任務,立即執(zhí)行打印11,將后續(xù) .then 微任務?放入微任務區(qū)記作 then3

        此時整個程序狀態(tài)如下:

        最后一遍:

        1. 執(zhí)行微任務區(qū)process3,打印10

        2. 執(zhí)行微任務區(qū)then3,打印12

        最終打印結果:1,7,6,8,2,4,3,5,9,11,10,12


        ? 作者?|??mmsmd

        來源 |??cnblogs.com/mmsmd/p/15370669.html


        加鋒哥微信:?java1239??
        圍觀鋒哥朋友圈,每天推送Java干貨!

        瀏覽 109
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            私人玩物麻酥酥 | 男女一进一出免费视频 | 男女日批网站 | 国产伦精品色情 | 一级做a爰片丝袜A片 | 老熟女大战农村熟妇91 | 亚洲精品午夜一区二区三区三区 | 影音av在线 | 淫香淫色图片 | 99热人人 |