一道有關 Javascript 事件循環的題目

前幾天在B站看到個視頻,講解了事件循環,裏面的有一道事件循環的題目,估計很多人不怎麼細心想的話會做錯。

題目內容:有如下代碼塊,請寫出點擊了 button 後,控制檯的輸出內容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="btn">click</button>
    <script>
        var oBtn = document.getElementById('btn')

        oBtn.addEventListener('click', function () {
            Promise.resolve().then(() => console.log('微任務 1'))
            console.log('listener1')
        })

        oBtn.addEventListener('click', function () {
            Promise.resolve().then(() => console.log('微任務 2'))
            console.log('listener2')
        })

    </script>
</body>
</html>

 答案: 

我個人的理解,先輸出 listener1 微任務1,後再輸出 listener2 微任務2,是因爲js是單線程執行的,所以事件肯定也是從第一個 EventListener 開始執行的。那麼在執行第一個的時候,由於 promise 是走微任務的,所以先輸出 listener1,接下來肯定有挺多人會認爲是要執行 Listener2 中的代碼了,但其實不是,在 javascript 的堆棧中,監聽 click 的事件結束了,在目前的微任務隊列中,裏面只有一個 Listener1 的 Promise,由於第2個 EventListener 還暫時沒執行到,所以就會輪到 Promise 的這個微任務了。以此類推,EventListener2 中的打印也是如此。

但是如果題目改成如下,控制檯將輸出什麼呢?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="btn">click</button>
    <script>
        var oBtn = document.getElementById('btn')

        oBtn.addEventListener('click', function () {
            Promise.resolve().then(() => console.log('微任務 1'))
            console.log('listener1')
        })

        oBtn.addEventListener('click', function () {
            Promise.resolve().then(() => console.log('微任務 2'))
            console.log('listener2')
        })
        
        oBtn.click()

    </script>
</body>
</html>

 答案:

那這個輸出怎麼是 listener1 listener2 先輸出後再輸出 微任務1 和 微任務2 啊?在 javascript 的堆棧中,click() 運行,然後依次執行 listener1 listener2 的事件,也就是先打印 listener1,將 微任務1 推入微任務隊列中,然後打印 listener2,將 微任務2 推入微任務隊列中,此時微任務隊列中,有兩個微任務,並且 click 事件執行完畢,javascript 堆棧中的 click() 已經執行結束,接下來就是執行按順序執行微任務隊列中的了,故有以上輸出。針對題目二,我手工畫了個簡單的草圖,大概表示一下過程:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章