溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JS運行機制實例分析

發(fā)布時間:2022-03-14 15:27:19 來源:億速云 閱讀:129 作者:iii 欄目:web開發(fā)

本篇內容主要講解“JS運行機制實例分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JS運行機制實例分析”吧!

1.為什么JS是單線程的?

JS的單線程,與它的用途有關。

作為瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操作DOM。這決定了它只能是單線程,否則會帶來很復雜的同步問題。

比如,假定JavaScript同時有兩個線程,一個線程在某個DOM節(jié)點上添加內容,另一個線程刪除了這個節(jié)點,這時瀏覽器應該以哪個線程為準

但是瀏覽器是多線程的

2.事件循環(huán)機制中的兩種任務

宏任務:整體代碼,setTimeout,setInterval等

微任務:new Promise ().then的回調,MutationObserver(前端回溯)用來監(jiān)聽事件的改變的

3.為什么要引入微任務的概念,只有宏任務不行嗎

宏任務遵循先進先出的原則執(zhí)行,但是如果在宏任務執(zhí)行的過程中有了優(yōu)先級更高的任務需要先執(zhí)行,那么此時往任務隊列中添加新任務的話,因為宏任務秉持著先進先出的原則,新添加的任務也只能是被排在后面的,那是萬萬不行的,所以才引入了微任務

4.事件循環(huán)

先執(zhí)行同步,再執(zhí)行異步,異步中先執(zhí)行微任務再執(zhí)行宏任務

首先,整體的js代碼(作為第一個宏任務)開始執(zhí)行的時候,會把所有代碼分為同步任務、異步任務兩部分,

同步任務會直接進入主線程依次執(zhí)行,同步任務執(zhí)行完后,執(zhí)行異步任務,

異步任務會再分為宏任務和微任務,

微任務中先執(zhí)行同步任務,異步任務依舊放到任務隊列中排隊,

當主線程空閑的時候,任務隊列中異步任務再依次執(zhí)行

上述過程會不斷重復,這就是Event Loop,比較完整的事件循環(huán)

5.Promise

new Promise(() => {}).then()

敲黑板劃重點——

前面的 new Promise() 這一部分是一個構造函數,這是一個同步任務

后面的 .then() 才是一個異步微任務

new Promise((resolve) => {

console.log(1)

  resolve()

}).then(()=>{

console.log(2)

})

console.log(3)

//上面代碼輸出1 3 2

6.async / await 

async/await本質上還是基于Promise的一些封裝,而Promise是屬于微任務的一種

所以在使用await關鍵字與Promise.then效果類似

setTimeout(() => console.log(4))

async function test() {

  console.log(1)

  await Promise.resolve()

  console.log(3)

}

test()

console.log(2)

//上述代碼輸出1 2 3 4

setTimeout(() => console.log(4))

async function test() {

  console.log(1)

  await async2()

  console.log(3)

 }

function async2() {

  console.log(5);

 }

test()

console.log(2)

//上述代碼輸出1 5 2 3 4

await 修飾的函數及以前的代碼,相當于與 new Promise 的同步代碼

await 以后的代碼相當于 Promise.then的異步

7.附上幾道面試題

function test() {

  console.log(1)

  setTimeout(function () { 

    console.log(2)

  }, 1000)

}

test();

setTimeout(function () {

  console.log(3)

})

new Promise(function (resolve) {

  console.log(4)

  setTimeout(function () {

    console.log(5)

  }, 100)

  resolve()

}).then(function () {

  setTimeout(function () {

    console.log(6)

  }, 0)

  console.log(7)

})

console.log(8)

//上述代碼輸出 1、4、8、7、3、6、5、2

    async function async1() {

      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);

    async1();

    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'

    //await async2();

    //相當于 new Promise((resolve) => {

        async2();

        resolve();

      }).then(() => { console.log('async1 end') })

    console.log('start');

    setTimeout(() => {

      console.log('children2');

      Promise.resolve().then(() => {

        console.log('children3');

      })

    }, 0);

    new Promise((resolve, reject) => {

      console.log('children4');

      setTimeout(() => {

        console.log('children5');

        resolve('children6')

      }, 0);

    }).then(res => {

      console.log('children7');

      setTimeout(() => {

        console.log(res);

      }, 0);

    })

    // 上述代碼輸出

    //'start'

    //'children4'

    //第一輪宏任務結束,發(fā)現(xiàn)沒有微任務,原因:new Promise里并沒有resolve(),只有resolve()才會把.then放到微任務里

    //'children2'

    //'children3'

    //'children5'

    //'children7'

    //'children6'

    const p = function () {

      return new Promise((resolve, reject) => {

        const p1 = new Promise((resolve, reject) => {

          setTimeout(() => {

            resolve(1)

          }, 0);

          resolve(2)

        })

        p1.then(res => {

          console.log(res);

        })

        console.log(3);

        resolve(4)

      })

    }

    p().then(res => {

      console.log(res);

    })

    console.log('end');

    // 上述代碼輸出

    //3

    //end

    //Promise的狀態(tài)是唯一且不可改變的,所有當resolve(2)的時候.then已經被輸出了,setTimeout里的resolve(1)就沒有了

    //2

    //4

到此,相信大家對“JS運行機制實例分析”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

js
AI