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>

        這次徹底搞懂瀏覽器的事件循環(huán)知識它、!(面試必備)

        共 9579字,需瀏覽 20分鐘

         ·

        2021-04-14 02:46

        文末標(biāo)注領(lǐng)取文章中所有源碼的方式

        關(guān)于事件循環(huán)的問題面試官都尤其的偏愛,所以說準(zhǔn)備面試如果不搞懂事件循環(huán)是非常危險的。

        當(dāng)面試官問你了解瀏覽器事件循環(huán)嗎?這只是一個開始,接下來:

        • 為什么js在瀏覽器中有事件循環(huán)機(jī)制
        • 事件循環(huán)有哪些任務(wù)
        • 為什么要用微任務(wù),只有宏任務(wù)不行嗎
        • 瀏覽器中事件循環(huán)機(jī)制怎么執(zhí)行的?與Node中有何區(qū)別
        • setTimeout為什么沒有按寫好的延遲時間執(zhí)行?
        • ...

        這一系列圍繞事件循環(huán)的問題都有可能會一步一步的讓你回答

        本文圍繞以下幾個內(nèi)容來展開,讓你輕松的回答面試官關(guān)于事件循環(huán)系列問題。

        圖片.png

        為什么會有事件循環(huán)機(jī)制

        JavaScript的一大特點就是單線程,也就是說,同一時間只能做一件事。那為什么要設(shè)計成單線程呢,多線程效率不是更高嗎?

        有這樣一個場景:假定JavaScript同時有兩個線程,一個線程在某個DOM節(jié)點上添加內(nèi)容,另一個線程刪除了這個節(jié)點,這時瀏覽器應(yīng)該以哪個線程為準(zhǔn)?

        所以,JavaScript從誕生就是單線程。但是單線程就導(dǎo)致有很多任務(wù)需要排隊,只有一個任務(wù)執(zhí)行完才能執(zhí)行后一個任務(wù)。如果某個執(zhí)行時間太長,就容易造成阻塞;為了解決這一問題,JavaScript引入了事件循環(huán)機(jī)制

        事件循環(huán)是什么

        Javascript單線程任務(wù)被分為同步任務(wù)異步任務(wù)

        • 同步任務(wù):立即執(zhí)行的任務(wù),在主線程上排隊執(zhí)行,前一個任務(wù)執(zhí)行完畢,才能執(zhí)行后一個任務(wù);
        • 異步任務(wù):異步執(zhí)行的任務(wù),不進(jìn)入主線程, 而是在異步任務(wù)有了結(jié)果后,將注冊的回調(diào)函數(shù)放入任務(wù)隊列中等待主線程空閑的時候讀取執(zhí)行。

        注意:異步函數(shù)在相應(yīng)輔助線程中處理完成后,即異步函數(shù)達(dá)到觸發(fā)條件了,就把回調(diào)函數(shù)推入任務(wù)隊列中,而不是說注冊一個異步任務(wù)就會被放在這個任務(wù)隊列中

        同步任務(wù)與異步任務(wù)流程圖:

        從上面流程圖中可以看到,主線程不斷從任務(wù)隊列中讀取事件,這個過程是循環(huán)不斷的,這種運行機(jī)制就叫做Event Loop(事件循環(huán))!

        事件循環(huán)中的兩種任務(wù)

        在JavaScript中,除了廣義的同步任務(wù)和異步任務(wù),還可以細(xì)分,一種是宏任務(wù)(MacroTask)也叫Task,一種叫微任務(wù)(MicroTask)。

        二者執(zhí)行順序流程圖如下:

        每次單個宏任務(wù)執(zhí)行完畢后, 檢查微任務(wù)隊列是否為空, 如果不為空,會按照先入先出的規(guī)則全部執(zhí)行完微任務(wù)后, 清空微任務(wù)隊列, 然后再執(zhí)行下一個宏任務(wù),如此循環(huán)

        如何區(qū)分宏任務(wù)與微任務(wù)呢?

        • 宏任務(wù):macrotask,又稱為task,  可以理解為每次執(zhí)行棧執(zhí)行的代碼就是一個宏任務(wù)(包括每次從事件隊列中獲取一個事件回調(diào)并放到執(zhí)行棧中執(zhí)行)。

        一般包括:script(可以理解為外層同步代碼)、setTimeout、setInterval 、setImmediate、I/O操作

        • 微任務(wù):microtask, 又稱為job, 可以理解是在當(dāng)前 task 執(zhí)行結(jié)束后立即執(zhí)行的任務(wù)。包括:Promise.then/cath /finally回調(diào)(平時常見的)、 MutationObserver回調(diào)(html5新特性)

        為什么要有微任務(wù)呢?

        既然我們知道了微任務(wù)與宏任務(wù),但異步任務(wù)為什么要區(qū)分宏任務(wù)與微任務(wù)呢,只有宏任務(wù)不可以嗎?

        因為事件隊列其實是一個“先進(jìn)先出”的數(shù)據(jù)結(jié)構(gòu),排在前面的事件會優(yōu)先被主線程讀取, 那如果突然來了一個優(yōu)先級更高的任務(wù),還讓去人家排隊,就很不理性化, 所以需要引入微任務(wù)。

        舉一個現(xiàn)實生活中的例子:

        就是我們?nèi)ャy行辦理業(yè)務(wù)時, 并不是到了就能辦理, 而是需要先取號排隊, 等到柜臺業(yè)務(wù)員辦理完當(dāng)前客戶業(yè)務(wù)才能繼續(xù)叫號進(jìn)行下一個。

        這時每一個來辦理業(yè)務(wù)的人就可以認(rèn)為是銀行柜員的一個宏任務(wù)來存在, 當(dāng)辦理到你的業(yè)務(wù)時, 你本來只是要重新綁定一下手機(jī)號, 但是突然想到明天要參加婚禮,需要隨份子錢, 此時你和柜員說你要取money, 這時候柜員不能告訴你,讓你重新取號排隊(不合理的要求)。

        其實這時候就相當(dāng)于你突然提出了一個新的任務(wù),這個任務(wù)就相當(dāng)于是一個微任務(wù) ,它要在下一個宏任務(wù)之前完成。

        在當(dāng)前的微任務(wù)沒有執(zhí)行完成時,是不會執(zhí)行下一個宏任務(wù)的。

        面試中如果問到這里,基本已經(jīng)了解事件循環(huán)的理論掌握情況, 接下來可能就會說,來做一下下面幾道題吧, 考察你的實際理解到什么程度。

        事件循環(huán)典型題目分析

        案例1:代碼執(zhí)行結(jié)果是什么

        async function async1() {
            console.log("async1 start")
            await async2()
            console.log("async1 end")
        }

        async function async2(){
            console.log("async2")
        }

        console.log("script start")

        setTimeout(function(){
            console.log("setTimeout")
        }, 0)

        async1()

        new Promise(function(resolve){
            console.log("promise1")
            resolve()
        }).then(function(){
            console.log("promise2")
        })

        console.log("script end")

        這里我們討論瀏覽器中的執(zhí)行結(jié)果,分析:

        1. 建立執(zhí)行上下文,先執(zhí)行同步任務(wù),輸出『script start』

        2. 往下執(zhí)行,遇到setTimeout,將其回調(diào)函數(shù)放入宏任務(wù)隊列,等待執(zhí)行

        3. 繼續(xù)往下執(zhí)行,調(diào)用async1:

          1. 是同步任務(wù),輸出『async1 start』
          2. 接下來await async2(), 這里的代碼相當(dāng)于new Promise(()=>{async2()}),而將 await 后面的全部代碼放到.then()中去;所以輸出『async2』,把async2()后面的代碼放到微任務(wù)中
        4. 繼續(xù)執(zhí)行,有個new Promise 輸出『promise1』,當(dāng)resolve后,將.then()的回調(diào)函數(shù)放到微任務(wù)隊列中(記住Promise本身是同步的立即執(zhí)行函數(shù),then是異步執(zhí)行函數(shù))。

        5. 繼續(xù)往下執(zhí)行, 輸出『script end』,此時調(diào)用棧被清空,可以執(zhí)行異步任務(wù)

        6. 開始第一次事件循環(huán):7.1 由于整個script 算一個宏任務(wù),因此該宏任務(wù)已經(jīng)執(zhí)行完畢 7.2 檢查微任務(wù)隊列, 發(fā)現(xiàn)其中放入了2個微任務(wù)(分別在3.2步,4步放入), 執(zhí)行輸出『async1 end』,『promise2』,第一次循環(huán)結(jié)束

        7. 開始第二次循環(huán):

          1. 從宏任務(wù)開始, 檢查宏任務(wù)隊列中有setTimeout回調(diào), 輸出『setTimeout』
          2. 檢查微任務(wù)隊列,無可執(zhí)行的微任務(wù), 第二次循環(huán)結(jié)束

        注意:async/await底層是基于Promise封裝的,所以await前面的代碼相當(dāng)于new Promise,是同步進(jìn)行的,await后面的代碼相當(dāng)于.then回調(diào),才是異步進(jìn)行的。

        最后執(zhí)行結(jié)果如下:

        script start
        async1 start
        async2
        promise1
        script end
        async1 end
        promise2
        setTimeout

        關(guān)于第3步代碼執(zhí)行分析:

        async function async1() {
            console.log("async1 start")
            await async2()
            console.log("async1 end")
        }

        改為Promise寫法就是:

        async function async1() {
        new Promise((resolve, reject) =>{
            console.log("async1 start")
            resolve(async2())
        }).then(()=>{
            // 執(zhí)行 async1 函數(shù)await之后的語句
            console.log("async1 end")
        })
        }

        再看下面一道題

        案例2:代碼執(zhí)行結(jié)果是什么

        console.log("start");
        setTimeout(() => {
            console.log("children2")
            Promise.resolve().then(() =>{
                console.log("children3")
            })
        }, 0)

        new Promise(function(resolve, reject){
            console.log("children4")
            setTimeout(function(){
                console.log("children5")
                resolve("children6")
            }, 0)
        }).then(res =>{
            console.log("children7")
            setTimeout(() =>{
                console.log(res)
            }, 0)
        })

        分析執(zhí)行順序:

        1. 首先將整體代碼作為一個宏任務(wù)執(zhí)行,輸出『start』

        2. 接著遇到setTimeout,0ms后將其回調(diào)函數(shù)放入宏任務(wù)隊列

        3. 接下來遇到Promise, 由于Promise本身是立即執(zhí)行函數(shù), 所以先輸出『children4』

          3-1. 在Promise中遇到setTimeout, 將其回調(diào)放入宏任務(wù)隊列中;整體代碼執(zhí)行完畢

        4. 然后檢查并執(zhí)行所有微任務(wù), 因為沒有微任務(wù), 所以第一次事件循環(huán)結(jié)束,開始第二輪

        5. 執(zhí)行第2步放入的宏任務(wù),輸出『children2』 5-1. 遇到Promise,并直接調(diào)用了resolve ,將.then回調(diào)加入都微任務(wù)隊列中

        6. 檢查并執(zhí)行所有微任務(wù), 輸出『children3』, 沒有多余的微任務(wù), 所以第二輪事件循環(huán)結(jié)束,開始第三輪事件循環(huán)

        7. 執(zhí)行3-1中放入的宏任務(wù), 輸出『children5』, 并且調(diào)用了resolve, 所以將對應(yīng)的.then回調(diào)放入到微任務(wù)隊列中

        8. 檢查并執(zhí)行所以微任務(wù), 輸出『children7』,遇到setTimeout,將其加入到宏任務(wù)隊列中,開始第四輪事件循環(huán)

        9. 執(zhí)行第8步加入的宏任務(wù), 輸出『children6』, 沒有任何微任務(wù), 第四輪事件循環(huán)結(jié)束。

        最后執(zhí)行結(jié)果:

        start
        children4
        children2
        children3
        children5
        children7
        children6

        注意:有的小伙伴在第3步中容易錯誤的將.then的回調(diào)放入微任務(wù)隊列;因為沒有調(diào)用resolve或者reject之前是不算異步任務(wù)完成的, 所以不能將回調(diào)放入事件隊列

        Node和瀏覽器的事件循環(huán)的區(qū)別?

        Node的事件循環(huán)是libuv實現(xiàn)的,引用一張官網(wǎng)的圖:

        Node的事件循環(huán)

        圖中表示的是事件循環(huán)包含的6個階段,大體的task(宏任務(wù))執(zhí)行順序是這樣的:

        • timers定時器:本階段執(zhí)行已經(jīng)安排的 setTimeout()setInterval() 的回調(diào)函數(shù)。
        • pending callbacks待定回調(diào):執(zhí)行延遲到下一個循環(huán)迭代的 I/O 回調(diào)。
        • idle, prepare:僅系統(tǒng)內(nèi)部使用,可以不必理會。
        • poll 輪詢:檢索新的 I/O 事件;執(zhí)行與 I/O 相關(guān)的回調(diào)(幾乎所有情況下,除了關(guān)閉的回調(diào)函數(shù),它們由計時器和 setImmediate() 排定的之外),其余情況 node 將在此處阻塞。
        • check 檢測:setImmediate() 回調(diào)函數(shù)在這里執(zhí)行。
        • close callbacks 關(guān)閉的回調(diào)函數(shù):一些準(zhǔn)備關(guān)閉的回調(diào)函數(shù),如:socket.on('close', ...)。

        首先需要知道的是Node版本不同,執(zhí)行順序有所差異。因為Node v11之后, 事件循環(huán)的原理發(fā)生了變化,和瀏覽器執(zhí)行順序趨于一致,都是每執(zhí)行一個宏任務(wù)就執(zhí)行完微任務(wù)隊列。

        Node v10及以前,微任務(wù)和宏任務(wù)在Node的執(zhí)行順序:

        1. 執(zhí)行完一個階段的所有任務(wù)
        2. 執(zhí)行完nextTick隊列里面的內(nèi)容
        3. 然后執(zhí)行完微任務(wù)隊列的內(nèi)容

        Node v10及以前的版本,微任務(wù)會在事件循環(huán)的各個階段之間執(zhí)行,也就是一個階段執(zhí)行完畢,就會去執(zhí)行微任務(wù)隊列的任務(wù):

        圖片.png

        瀏覽器與Node執(zhí)行順序分別是什么

        setTimeout(()=>{
            console.log('timer1')

            Promise.resolve().then(function() {
                console.log('promise1')
            })
        }, 0)

        setTimeout(()=>{
            console.log('timer2')

            Promise.resolve().then(function() {
                console.log('promise2')
            })
        }, 0)

        // 瀏覽器中:
        timer1
        promise1
        timer2
        promise2

        // 在Node中:
        timer1
        timer2
        promise1
        promise2

        在這個例子中,Node的邏輯如下(再強(qiáng)調(diào)一下Node v10及以下):

        最初timer1和timer2就在timers階段中。開始時首先進(jìn)入timers階段,執(zhí)行timer1的回調(diào)函數(shù),打印timer1,并將promise1.then回調(diào)放入微任務(wù)隊列,同樣的步驟執(zhí)行timer2,打印timer2;至此,timer階段執(zhí)行結(jié)束,event loop進(jìn)入下一個階段之前,執(zhí)行微任務(wù)隊列的所有任務(wù),依次打印promise1、promise2。

        setImmediate 的setTimeout的區(qū)別

        setImmediate大部分瀏覽器暫時不支持,只有IE10、11支持,具體可見MDN。setImmediatesetTimeout是相似的,但根據(jù)它們被調(diào)用的時間以不同的方式表現(xiàn)。

        • setImmediate設(shè)計用于在當(dāng)前poll階段完成后check階段執(zhí)行腳本 。
        • setTimeout 安排在經(jīng)過最?。╩s)后運行的腳本,在timers階段執(zhí)行。

        舉個例子:

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

        setImmediate(() => {
          console.log('setImmediate');
        });

        其執(zhí)行順序為:

        遇到setTimeout,雖然設(shè)置的是0毫秒觸發(fā),但是被node.js強(qiáng)制改為1毫秒,塞入times階段 遇到setImmediate塞入check階段 同步代碼執(zhí)行完畢,進(jìn)入Event Loop 先進(jìn)入times階段,檢查當(dāng)前時間過去了1毫秒沒有,如果過了1毫秒,滿足setTimeout條件,執(zhí)行回調(diào),如果沒過1毫秒,跳過 跳過空的階段,進(jìn)入check階段,執(zhí)行setImmediate回調(diào) 可見,1毫秒是個關(guān)鍵點,所以在上面的例子中,setImmediate不一定在setTimeout之前執(zhí)行了。

        process.nextTick()與 Promise回調(diào)誰先執(zhí)行?

        process.nextTick()是Node環(huán)境下的方法, 所以我們基于Node談?wù)摗?/p>

        process.nextTick()是一個特殊的異步API,其不屬于任何的Event Loop階段。事實上Node在遇到這個API時,Event Loop根本就不會繼續(xù)進(jìn)行,會馬上停下來執(zhí)行process.nextTick(),這個執(zhí)行完后才會繼續(xù)Event Loop??梢钥匆幌聜€例子:

        var fs = require('fs')

        fs.readFile(__filename, () => {
            setTimeout(() => {
                console.log('setTimeout');
            }, 0);

            setImmediate(() => {
                console.log('setImmediate');
                
                process.nextTick(() => {
                  console.log('nextTick 2');
                });
            });

            process.nextTick(() => {
              console.log('nextTick 1');
            });
        });

        // 執(zhí)行結(jié)果
        nextTick 1
        setImmediate
        nextTick 2
        setTimeout

        執(zhí)行流程梳理:

        1. 代碼都在readFile回調(diào)中,回調(diào)執(zhí)行時處于poll階段
        2. 遇到setTimeout,雖然延時設(shè)置的是0, 但是相當(dāng)于setTimeout(fn,1),將其回調(diào)函數(shù)放入后面的timers階段
        3. 接下來遇到setImmediate,將其回調(diào)函數(shù)放入到后面的check階段
        4. 遇到process.nextTick, 立即執(zhí)行, 輸出 『nextTick 1』
        5. 執(zhí)行到下一個階段check,輸出『setImmediate』, 又遇到nextTick,執(zhí)行輸出『nextTick 2』
        6. 執(zhí)行到下一個timers階段, 輸出『setTimeout』

        這種機(jī)制其實類似于我們前面講的微任務(wù),但是并不完全一樣,比如同時有nextTickPromise的時候,肯定是nextTick先執(zhí)行,原因是nextTick的隊列比Promise隊列優(yōu)先級更高。來看個例子:

        setImmediate(() => {
          console.log('setImmediate');
        });
        Promise.resolve().then(()=>{
            console.log('promise')
        })
        process.nextTick(()=>{
            console.log('nextTick')
        })

        // 運行結(jié)果
        nextTick
        promise
        setImmediate

        總結(jié)

        文章包含了為什么會有事件循環(huán), 事件循環(huán)是什么,事件循環(huán)的運行機(jī)制以及Node和瀏覽器中事件循環(huán)的異同點,通過文章的學(xué)習(xí), 面對開篇提出的面試題,相信你都可以輕松的搞定。

        關(guān)注公眾號【前端飯圈】獲取文章中的源碼, 另外還準(zhǔn)備了10道關(guān)于事件循環(huán)的面試題, 如果你想檢測以下自己是否完全掌握,可以領(lǐng)取題目, 回復(fù)【事件循環(huán)】即可領(lǐng)取。


        參考文章:

        https://www.ruanyifeng.com/blog/2014/10/event-loop.html

        https://my.oschina.net/u/4390738/blog/3199580

        https://www.jianshu.com/p/23fad3814398

        https://juejin.cn/post/6844904004653154317

        - EOF -


        END



        如果覺得這篇文章還不錯
        點擊下面卡片關(guān)注我
        來個【分享、點贊、在看】三連支持一下吧

           “分享、點贊、在看” 支持一波  

        瀏覽 96
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報
        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>
            永久免费黄色视频| 日本韩国叼嘿片| 亚洲精品高清无码| 三级视频网| 色老板视频在线观看| 午夜av在线免费观看| 美女扣逼网站| 久久国产2025| 欧美亚洲小说| 韩日不卡视频| MAD033_后宫秘密陶子.| 影音先锋一区二区| 日韩黄色在线观看| 国产—a毛—a毛A免费| www.精品视频| 色呦呦在线| 国产第一精品| 成人无码观看| 国产免费一级特黄A片| 搡BBB搡BBBB搡BBBB'| 日本亚洲视频| 91人体视频| 成人h网站在线观看| 国产色天使| 亚洲激情| 69av在线| 亚洲精品久久久久中文字幕二区| 熟女人妻人妻の视频| 成人免费黄色| 亚洲精品国产精品国自产曰本| 亚洲无码成人网| 九九精品视频在线观看| 91无码秘蜜桃一区二区三区-百度 精品人妻一区二区三区在线视频不卡 | 国产迷奸视频| 亚洲九区| 嘉兴少妇按摩69XX| 内射老熟女| 国内不卡一卡二视频| 玖玖综合网| 日韩国产免费| 人人操人人人| 国产69视频在线观看| 中日韩黄色视频| 色色射| 欧美日韩岛国| 日韩免费在线观看| 大香蕉伊人网在线| 日韩免费Av| 1024国产在线| 五月天婷婷国产| 国产精品久久久一区二区三区| 有码在线播放| 成人aV免费观看| 东方美美高清无码一区| 高清无码免费视频| 国产777| 一区二区精品| 操B网站| 人人操人人色| 黄色三级网站| 亚洲在线免费观看| 五月天综合网| 亚洲天堂无码a| 久久久久久久久久国产精品免费观看-百度 | 久久爆乳一区二区三区| 成人精品三级AV在线看| 中文字幕在线日韩| 国产成人无码A片免费看| 手机av在线| 午夜精品秘一区二区三区| 精品三区| 免费A片视频| 免费在线观看AV| 丁香六月婷婷久久综合| 日本爱爱视频| 香蕉婷婷亚洲丁香| 黑人vs亚洲人在线播放| 欧美亚洲国产精品| 久久婷婷久久| 亚洲色情在线播放| 人人艹在线观看| 欧洲精品在线免费观看| 欧美一级A片免费看视频小说| 亚洲男女内射| 成人网站大香蕉| 韩国无码高清视频| 青青操视频在线| 中文字幕日本人妻| 无码免费毛片一区二区三区古代| 超碰人人网| 亚洲综合精品| 97日日| 无码一区二区在线观看| 你懂的在线网站| 狠狠婷婷| 安徽妇搡BBB搡BBBB户外老太太 | 久久久国产精品人人片| 俺去吔| 美日韩一级| 欧美男女操逼视频| 成人自拍电影| AV无码一区二区三区| 一级日逼视频| 日韩精品一二区| 插菊花综合网站| 蜜桃AV在线播放| 九九九成人| 欧美日韩国产一区二区三区| 久久久精品人妻| 中文久久| 免费中文字幕视频| 国产51视频| 亚洲日韩在线视频播放| 99久免费视频| 操逼视频电影| 人人做人人做人人做,人人做全句下一 | 在线播放亚洲| 四川BBB搡BBB爽爽爽电影| 成人电影久久久| 国产五月婷婷| 午夜福利成人视频| 亚洲成人av在线| 99re国产| 九九操比| 人人干AV| 蜜芽视频| 波多野结衣一二三区| 亚洲中文字幕观看| 中文字幕无码视频在线观看| 老鸭窝在线观看视频| 婷婷五月在线视频| 蜜桃传媒一区二区| 日韩肏屄视频在线观看| av免费观看网站| 在线观看欧美黄片| 免费看黄色视频的网站| 极品一线天小嫩嫩真紧| 特级毛片WWW| 大香蕉性爱视频| 玖玖在线视频| 亚洲无码AV麻豆| 欧美激情xxx| 伊人激情五月| 日韩人妻无码电影| 99视频这里有精品| 黑人一级| 天天操网| 欧美性猛交一区二区三区| 欧美一道本在线| www.青草视频| 三级网址在线| 无套内射学生妹去看片| 久久无码高清视频| 在线观看黄色视频网站| 欧美footjob高跟脚交| 久久午夜无码鲁丝午夜精品| 91无码人妻精品一区二区三区四| 亚洲天堂影音先锋| 亚洲无码18禁| 亚洲人在线| 日韩精品区| 黑人又粗又大XXXXOO| 免费高清无码在线| 亚洲xx网| 内射免费网站| 亚洲五月丁香| 亚洲综合色网| 青草大香蕉| 9l人人澡人人妻人人精品| 亚洲一区久久| 免费AV在线播放| 综合成人| 大香蕉久久视频| 国内自拍2025| 国产三级性爱视频| 免费看黄色的视频| 日本欧美视频| 69超碰| 久草网大香蕉| 高清在线无码视频| 三级成人在线| 99热r| 久久久91| 亚洲AV无码乱码AV| 黄色av网站在线观看| 午夜在线免费视频| 成人毛片在线播放| 午夜国产在线| 久久久久久三级电影| 91探花秘入囗| 91视频在线网站| 青青艹在线视频| 国产无码免费视频| 中文无码熟妇一区二区| 久视频在线观看| 撸一撸AV| 黄片免费观看网站| 国产福利在线| 亚洲成人第一网站| 91麻豆一区| 黄色成人网站在线播放| 欧美日韩三级| 欧美成人一级片| 西西444www无码精品| 猛男大粗猛爽h男人味| 一区二区无码视频| 国产三级片精品| 日韩大香蕉| 国产成人亚洲综合A∨婷婷| 天堂亚洲精品| 久操手机在线| 三级在线网站| 中文一区| 裸体美女视频欧美18| 嫩小槡BBBB槡BBBB槡漫画| 亚洲无码高清在线| 北条麻妃无码视频在线| 天堂色色| 人妻无码在线视频| 日本韩国叼嘿片| 国产思思99re99在线观看| 91无码成人| 色444| 国产嫩草久久久一二三久久免费观看 | 蜜芽成人在线| 久久福利导航| 无码在线视频播放| 99久久久精品| 丰满的人妻一区二区三区果冻| 乌克兰xxxx| 黄色片久久| 无码成人AV| 欧美中文字幕在线| 69激情网| 天堂网AV在线| 亚洲综合免费观看| 成人a片在线免费观看| 免费观看一级毛一片| ThePorn日本无码| 国产777| 91亚洲一区| 日韩欧美国产成人| 欧美日屄| 日本少妇性爱视频| 亚洲AV无码精品久久一区二区 | 欧美午夜成人| 午夜成人大片| 肏屄视频网| 日韩乱伦电影| 激情小说亚洲图片:伦| 丰滿人妻一区二区三| 四虎黄色片| 婷婷色色婷婷五月天| 中文字幕乱码中文乱码图片| 青青青草视频在线观看| 综合伊人| 中文字幕精品三区无码| 国产又爽又黄免费网站在线| 欧美三级片在线播放| 综合天堂| 中国一级黄色毛片| 午夜免费视频| 日韩看片| 五月丁香婷婷激情综合| 麻豆影音先锋| 久久大香| 91国产精品在线视频| 久久牛牛| 国产高清免费视频| 黄色免费福利视频| 性爱一级| 日批视频网站| 在线观看无码AV| 日韩一级片免费看| 香蕉视频国产| 在线观看中文字幕视频| 一本色道无码道| 少妇免费视频| 男女免费av| 人人爱天天做| 国产成人免费| 三级AV在线观看| 五月天激情性爱| 国产成人在线视频| 91.xxxx| 五月天狠狠操| 免费中文字幕| 呦小性Free小U女HD| 草久网| 亚洲午夜久久久久久久久久久| 激情国产精品| www.91国产| 永久免费看片视频5355| 最新毛片网站| 成人精品午夜无码免费| 黄色视频网站日本| 操逼逼综合网| 欧美精品久久久久久久多人混战| 成人毛片视频网站| 亚洲1区2区|