精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

面試率超高的JS事件循環(huán),看這篇就夠了

開發(fā) 前端
事件循環(huán)是 JavaScript 中一個非常重要的概念,下面就來看看瀏覽器和 Node.js 中的事件循環(huán)的原理,以及兩者之間的差異!

大家好,我是 CUGGZ。

事件循環(huán)是 JavaScript 中一個非常重要的概念,下面就來看看瀏覽器和 Node.js 中的事件循環(huán)的原理,以及兩者之間的差異!

1、異步執(zhí)行原理

(1)單線程的JavaScript

我們知道,JavaScript是一種單線程語言,它主要用來與用戶互動,以及操作DOM。

JavaScript 有同步和異步的概念,這就解決了代碼阻塞的問題:

  • 同步:如果在一個函數(shù)返回的時候,調(diào)用者就能夠得到預(yù)期結(jié)果,那么這個函數(shù)就是同步的。
  • 異步:如果在函數(shù)返回的時候,調(diào)用者還不能夠得到預(yù)期結(jié)果,而是需要在將來通過一定的手段得到,那么這個函數(shù)就是異步的。

那單線程有什么好處呢?

  • 在 JS 運(yùn)行的時候可能會阻止 UI 渲染,這說明了兩個線程是互斥的。這是因?yàn)?JS 可以修改 DOM,如果在 JS 執(zhí)行的時候 UI 線程還在工作,就可能導(dǎo)致不能安全的渲染 UI。
  • 得益于 JS 是單線程運(yùn)行的,可以達(dá)到節(jié)省內(nèi)存,節(jié)約上下文切換時間的好處。

(2)多線程的瀏覽器

JS 是單線程的,在同一個時間只能做一件事情,那為什么瀏覽器可以同時執(zhí)行異步任務(wù)呢?

這是因?yàn)闉g覽器是多線程的,當(dāng) JS 需要執(zhí)行異步任務(wù)時,瀏覽器會另外啟動一個線程去執(zhí)行該任務(wù)。也就是說,JavaScript是單線程的指的是執(zhí)行JavaScript代碼的線程只有一個,是瀏覽器提供的JavaScript引擎線程(主線程)。除此之外,瀏覽器中還有定時器線程、 HTTP 請求線程等線程,這些線程主要不是來執(zhí)行 JS 代碼的。

比如主線程中需要發(fā)送數(shù)據(jù)請求,就會把這個任務(wù)交給異步 HTTP 請求線程去執(zhí)行,等請求數(shù)據(jù)返回之后,再將 callback 里需要執(zhí)行的 JS 回調(diào)交給 JS 引擎線程去執(zhí)行。也就是說,瀏覽器才是真正執(zhí)行發(fā)送請求這個任務(wù)的角色,而 JS 只是負(fù)責(zé)執(zhí)行最后的回調(diào)處理。所以這里的異步不是 JS 自身實(shí)現(xiàn)的,而是瀏覽器為其提供的能力。

下圖是Chrome瀏覽器的架構(gòu)圖:

圖片

可以看到,Chrome不僅擁有多個進(jìn)程,還有多個線程。以渲染進(jìn)程為例,就包含GUI渲染線程、JS引擎線程、事件觸發(fā)線程、定時器觸發(fā)線程、異步HTTP請求線程。這些線程為 JS 在瀏覽器中完成異步任務(wù)提供了基礎(chǔ)。

2、瀏覽器事件循環(huán)

JavaScript的任務(wù)分為兩種同步和異步:

  • 同步任務(wù): 在主線程上排隊執(zhí)行的任務(wù),只有一個任務(wù)執(zhí)行完畢,才能執(zhí)行下一個任務(wù),
  • 異步任務(wù): 不進(jìn)入主線程,而是放在任務(wù)隊列中,若有多個異步任務(wù)則需要在任務(wù)隊列中排隊等待,任務(wù)隊列類似于緩沖區(qū),任務(wù)下一步會被移到執(zhí)行棧然后主線程執(zhí)行調(diào)用棧的任務(wù)。

上面提到了任務(wù)隊列和執(zhí)行棧,下面就先來看看這兩個概念。

(1)執(zhí)行棧與任務(wù)隊列

執(zhí)行棧:從名字可以看出,執(zhí)行棧使用到的是數(shù)據(jù)結(jié)構(gòu)中的棧結(jié)構(gòu), 它是一個存儲函數(shù)調(diào)用的棧結(jié)構(gòu),遵循先進(jìn)后出的原則。它主要負(fù)責(zé)跟蹤所有要執(zhí)行的代碼。 每當(dāng)一個函數(shù)執(zhí)行完成時,就會從堆棧中彈出(pop)該執(zhí)行完成函數(shù);如果有代碼需要進(jìn)去執(zhí)行的話,就進(jìn)行 push 操作。以下圖為例:

圖片

當(dāng)執(zhí)行這段代碼時,首先會執(zhí)行一個 main 函數(shù),然后執(zhí)行我們的代碼。根據(jù)先進(jìn)后出的原則,后執(zhí)行的函數(shù)會先彈出棧,在圖中也可以發(fā)現(xiàn),foo 函數(shù)后執(zhí)行,當(dāng)執(zhí)行完畢后就從棧中彈出了。

JavaScript在按順序執(zhí)行執(zhí)行棧中的方法時,每次執(zhí)行一個方法,都會為它生成獨(dú)有的執(zhí)行環(huán)境(上下文),當(dāng)這個方法執(zhí)行完成后,就會銷毀當(dāng)前的執(zhí)行環(huán)境,并從棧中彈出此方法,然后繼續(xù)執(zhí)行下一個方法。

任務(wù)隊列: 從名字中可以看出,任務(wù)隊列使用到的是數(shù)據(jù)結(jié)構(gòu)中的隊列結(jié)構(gòu),它用來保存異步任務(wù),遵循先進(jìn)先出的原則。它主要負(fù)責(zé)將新的任務(wù)發(fā)送到隊列中進(jìn)行處理

JavaScript在執(zhí)行代碼時,會將同步的代碼按照順序排在執(zhí)行棧中,然后依次執(zhí)行里面的函數(shù)。當(dāng)遇到異步任務(wù)時,就將其放入任務(wù)隊列中,等待當(dāng)前執(zhí)行棧所有同步代碼執(zhí)行完成之后,就會從異步任務(wù)隊列中取出已完成的異步任務(wù)的回調(diào)并將其放入執(zhí)行棧中繼續(xù)執(zhí)行,如此循環(huán)往復(fù),直到執(zhí)行完所有任務(wù)。

JavaScript任務(wù)的執(zhí)行順序如下:

圖片

在事件驅(qū)動的模式下,至少包含了一個執(zhí)行循環(huán)來檢測任務(wù)隊列中是否有新任務(wù)。通過不斷循環(huán),去取出異步任務(wù)的回調(diào)來執(zhí)行,這個過程就是事件循環(huán),每一次循環(huán)就是一個事件周期。

(2)宏任務(wù)和微任務(wù)

任務(wù)隊列其實(shí)不止一種,根據(jù)任務(wù)種類的不同,可以分為微任務(wù)(micro task)隊列宏任務(wù)(macro task)隊列。常見的任務(wù)如下:

  • 宏任務(wù): script( 整體代碼)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 環(huán)境)。
  • 微任務(wù): Promise、MutaionObserver、process.nextTick(Node.js 環(huán)境)。

任務(wù)隊列執(zhí)行順序如下:

圖片

可以看到,Eventloop 在處理宏任務(wù)和微任務(wù)的邏輯時的執(zhí)行情況如下:

  1. JavaScript 引擎首先從宏任務(wù)隊列中取出第一個任務(wù);
  2. 執(zhí)行完畢后,再將微任務(wù)中的所有任務(wù)取出,按照順序分別全部執(zhí)行(這里包括不僅指開始執(zhí)行時隊列里的微任務(wù)),如果在這一步過程中產(chǎn)生新的微任務(wù),也需要執(zhí)行,也就是說在執(zhí)行微任務(wù)過程中產(chǎn)生的新的微任務(wù)并不會推遲到下一個循環(huán)中執(zhí)行,而是在當(dāng)前的循環(huán)中繼續(xù)執(zhí)行。
  3. 然后再從宏任務(wù)隊列中取下一個,執(zhí)行完畢后,再次將 microtask queue 中的全部取出,循環(huán)往復(fù),直到兩個 queue 中的任務(wù)都取完。

也是就是說,一次 Eventloop 循環(huán)會處理一個宏任務(wù)和所有這次循環(huán)中產(chǎn)生的微任務(wù)。

下面通過一個例子來體會事件循環(huán):

console.log('同步代碼1');

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

new Promise((resolve) => {
console.log('同步代碼2')
resolve()
}).then(() {
console.log('promise.then')
})

console.log('同步代碼3');

代碼輸出結(jié)果如下:

"同步代碼1"
"同步代碼2"
"同步代碼3"
"promise.then"
"setTimeout"

那這段代碼執(zhí)行過程是怎么的呢?

  1. 遇到第一個console,它是同步代碼,加入執(zhí)行棧,執(zhí)行并出棧,打印出"同步代碼1"。
  2. 遇到setTimeout,它是一個宏任務(wù),加入宏任務(wù)隊列。
  3. 遇到new Promise 中的console,它是同步代碼,加入執(zhí)行棧,執(zhí)行并出棧,打印出"同步代碼2"。
  4. 遇到Promise then,它是一個微任務(wù),加入微任務(wù)隊列。
  5. 遇到第三個console,它是同步代碼,加入執(zhí)行棧,執(zhí)行并出棧,打印出"同步代碼3"。
  6. 此時執(zhí)行棧為空,去執(zhí)行微任務(wù)隊列中所有任務(wù),打印出"promise.then"。
  7. 執(zhí)行完微任務(wù)隊列中的任務(wù),就去執(zhí)行宏任務(wù)隊列中的一個任務(wù),打印出"setTimeout"。

從上面的宏任務(wù)和微任務(wù)的工作流程中,可以得出以下結(jié)論:

  • 微任務(wù)和宏任務(wù)是綁定的,每個宏任務(wù)在執(zhí)行時,會創(chuàng)建自己的微任務(wù)隊列。
  • 微任務(wù)的執(zhí)行時長會影響當(dāng)前宏任務(wù)的時長。比如一個宏任務(wù)在執(zhí)行過程中,產(chǎn)生了 10 個微任務(wù),執(zhí)行每個微任務(wù)的時間是 10ms,那么執(zhí)行這 10 個微任務(wù)的時間就是 100ms,也可以說這 10 個微任務(wù)讓宏任務(wù)的執(zhí)行時間延長了 100ms。
  • 在一個宏任務(wù)中,分別創(chuàng)建一個用于回調(diào)的宏任務(wù)和微任務(wù),無論什么情況下,微任務(wù)都早于宏任務(wù)執(zhí)行(優(yōu)先級更高)。

那么問題來了,為什么要將任務(wù)隊列分為微任務(wù)和宏任務(wù)呢,他們之間的本質(zhì)區(qū)別是什么呢?

JavaScript在遇到異步任務(wù)時,會將此任務(wù)交給其他線程來執(zhí)行(比如遇到setTimeout任務(wù),會交給定時器觸發(fā)線程去執(zhí)行,待計時結(jié)束,就會將定時器回調(diào)任務(wù)放入任務(wù)隊列等待主線程來取出執(zhí)行),主線程會繼續(xù)執(zhí)行后面的同步任務(wù)。

對于微任務(wù),比如promise.then,當(dāng)執(zhí)行promise.then時,瀏覽器引擎不會將異步任務(wù)交給其他瀏覽器的線程去執(zhí)行,而是將任務(wù)回調(diào)存在一個隊列中,當(dāng)執(zhí)行棧中的任務(wù)執(zhí)行完之后,就去執(zhí)行promise.then所在的微任務(wù)隊列。

所以,宏任務(wù)和微任務(wù)的本質(zhì)區(qū)別如下:

  • 微任務(wù):不需要特定的異步線程去執(zhí)行,沒有明確的異步任務(wù)去執(zhí)行,只有回調(diào)。
  • 宏任務(wù):需要特定的異步線程去執(zhí)行,有明確的異步任務(wù)去執(zhí)行,有回調(diào)。

3、Node.js的事件循環(huán)

(1)事件循環(huán)的概念

對于Node.js的事件循環(huán),官網(wǎng)的描述如下:

When Node.js starts, it initializes the event loop, processes the provided input script (or drops into the REPL, which is not covered in this document) which may make async API calls, schedule timers, or call process.nextTick(), then begins processing the event loop.

翻譯一下就是:當(dāng)Node.js啟動時,它會初始化一個事件循環(huán),來處理輸入的腳本,這個腳本可能進(jìn)行異步API的調(diào)用、調(diào)度計時器或調(diào)用process.nextTick(),然后開始處理事件循環(huán)。

JavaScript和Node.js是基于V8 引擎的,瀏覽器中包含的異步方式在 NodeJS 中也是一樣的。除此之外,Node.js中還有一些其他的異步形式:

  • 文件 I/O:異步加載本地文件。
  • setImmediate():與 setTimeout 設(shè)置 0ms 類似,在某些同步任務(wù)完成后立馬執(zhí)行。
  • process.nextTick():在某些同步任務(wù)完成后立馬執(zhí)行。
  • server.close、socket.on('close',...)等:關(guān)閉回調(diào)。

這些異步任務(wù)的執(zhí)行就需要依靠Node.js的事件循環(huán)機(jī)制了。

Node.js 中的 Event Loop 和瀏覽器中的是完全不相同的東西。Node.js使用V8作為js的解析引擎,而I/O處理方面使用了自己設(shè)計的libuv,libuv是一個基于事件驅(qū)動的跨平臺抽象層,封裝了不同操作系統(tǒng)一些底層特性,對外提供統(tǒng)一的API,事件循環(huán)機(jī)制也是它里面的實(shí)現(xiàn)的,如下圖所示:

圖片

根據(jù)上圖,可以看到Node.js的運(yùn)行機(jī)制如下:

  1. V8引擎負(fù)責(zé)解析JavaScript腳本。
  2. 解析后的代碼,調(diào)用Node API。
  3. libuv庫負(fù)責(zé)Node API的執(zhí)行。它將不同的任務(wù)分配給不同的線程,形成一個Event Loop(事件循環(huán)),以異步的方式將任務(wù)的執(zhí)行結(jié)果返回給V8引擎。
  4. V8引擎將結(jié)果返回給用戶。

(2)事件循環(huán)的流程

其中l(wèi)ibuv引擎中的事件循環(huán)分為 6 個階段,它們會按照順序反復(fù)運(yùn)行。每當(dāng)進(jìn)入某一個階段的時候,都會從對應(yīng)的回調(diào)隊列中取出函數(shù)去執(zhí)行。當(dāng)隊列為空或者執(zhí)行的回調(diào)函數(shù)數(shù)量到達(dá)系統(tǒng)設(shè)定的閾值,就會進(jìn)入下一階段。下面 是Eventloop 事件循環(huán)的流程:

圖片

整個流程分為六個階段,當(dāng)這六個階段執(zhí)行完一次之后,才可以算得上執(zhí)行了一次 Eventloop 的循環(huán)過程。下面來看下這六個階段都做了哪些事:

  1. timers 階段:執(zhí)行timer(setTimeout、setInterval)的回調(diào),由 poll 階段控制。
  2. I/O callbacks 階段:主要執(zhí)行系統(tǒng)級別的回調(diào)函數(shù),比如 TCP 連接失敗的回調(diào)。
  3. idle, prepare 階段:僅Node.js內(nèi)部使用,可以忽略。
  4. poll 階段:輪詢等待新的鏈接和請求等事件,執(zhí)行 I/O 回調(diào)等。
  5. check 階段:執(zhí)行 setImmediate() 的回調(diào)。
  6. close callbacks 階段:執(zhí)行關(guān)閉請求的回調(diào)函數(shù),比如socket.on('close', ...)。

注意:上面每個階段都會去執(zhí)行完當(dāng)前階段的任務(wù)隊列,然后繼續(xù)執(zhí)行當(dāng)前階段的微任務(wù)隊列,只有當(dāng)前階段所有微任務(wù)都執(zhí)行完了,才會進(jìn)入下個階段,這里也是與瀏覽器中邏輯差異較大的地方。

其中,這里面比較重要的就是第四階段:poll,這一階段中,系統(tǒng)主要做兩件事:

  • 回到 timer 階段執(zhí)行回調(diào)。
  • 執(zhí)行 I/O 回調(diào)。

在進(jìn)入該階段時如果沒有設(shè)定了 timer 的話,會出現(xiàn)以下情況:

(1)如果 poll 隊列不為空,會遍歷回調(diào)隊列并同步執(zhí)行,直到隊列為空或者達(dá)到系統(tǒng)限制。

(2)如果 poll 隊列為空時,會出現(xiàn)以下情況:

  • 如果有 setImmediate 回調(diào)需要執(zhí)行,poll 階段會停止并且進(jìn)入到 check 階段執(zhí)行回調(diào)。
  • 如果沒有 setImmediate 回調(diào)需要執(zhí)行,會等待回調(diào)被加入到隊列中并立即執(zhí)行回調(diào),這里同樣會有個超時時間設(shè)置防止一直等待下去。

當(dāng)設(shè)定了 timer 且 poll 隊列為空,則會判斷是否有 timer 超時,如果有的就會回到 timer 階段執(zhí)行回調(diào)。

這一過程的具體執(zhí)行流程如下圖所示:

圖片

(3)宏任務(wù)和微任務(wù)

Node.js事件循環(huán)的異步隊列也分為兩種:宏任務(wù)隊列和微任務(wù)隊列。

  • 常見的宏任務(wù):setTimeout、setInterval、 setImmediate、script(整體代碼)、 I/O 操作等。
  • 常見的微任務(wù):process.nextTick、new Promise().then(回調(diào))等。

(4)process.nextTick()

上面提到了process.nextTick(),它是node中新引入的一個任務(wù)隊列,它會在上述各個階段結(jié)束時,在進(jìn)入下一個階段之前立即執(zhí)行。

Node.js官方文檔的解釋如下:

process.nextTick()is not technically part of the event loop. Instead, thenextTickQueuewill be processed after the current operation is completed, regardless of the current phase of the event loop. Here, an operation is defined as a transition from the underlying C/C++ handler, and handling the JavaScript that needs to be executed.

例如下面的代碼:

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

Promise.resolve().then(() {
console.error('promise')
})

process.nextTick(() {
console.error('nextTick')
})

輸出結(jié)果如下:

nextTick
promise
timeout

可以看到,process.nextTick()是優(yōu)先于promise的回調(diào)執(zhí)行。

(5)setImmediate 和 setTimeout

上面還提到了setImmediate 和 setTimeout,這兩者很相似,主要區(qū)別在于調(diào)用時機(jī)的不同:

  • setImmediate:在poll階段完成時執(zhí)行,即check階段。
  • setTimeout:在poll階段為空閑時,且設(shè)定時間到達(dá)后執(zhí)行,但它在timer階段執(zhí)行。

例如下面的代碼:

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

輸出結(jié)果如下:

timeout
setImmediate

在上面代碼的執(zhí)行過程中,第一輪循環(huán)后,分別將 setTimeout  和 setImmediate 加入了各自階段的任務(wù)隊列。第二輪循環(huán)首先進(jìn)入timers 階段,執(zhí)行定時器隊列回調(diào),然后 pending callbacks和poll 階段沒有任務(wù),因此進(jìn)入check 階段執(zhí)行 setImmediate 回調(diào)。所以最后輸出為timeout、setImmediate。###= 4. Node與瀏覽器事件循環(huán)的差異 Node.js與瀏覽器的事件循環(huán)的差異如下:

  • Node.js:microtask 在事件循環(huán)的各個階段之間執(zhí)行。
  • 瀏覽器:microtask 在事件循環(huán)的 macrotask 執(zhí)行完之后執(zhí)行。?圖片 ?

Nodejs和瀏覽器的事件循環(huán)流程對比如下:

  1. 執(zhí)行全局的 Script 代碼(與瀏覽器無差)。
  2. 把微任務(wù)隊列清空:注意,Node 清空微任務(wù)隊列的手法比較特別。在瀏覽器中,我們只有一個微任務(wù)隊列需要接受處理;但在 Node 中,有兩類微任務(wù)隊列:next-tick 隊列和其它隊列。其中這個 next-tick 隊列,專門用來收斂 process.nextTick 派發(fā)的異步任務(wù)。在清空隊列時,優(yōu)先清空 next-tick 隊列中的任務(wù),隨后才會清空其它微任務(wù)
  3. 開始執(zhí)行 macro-task(宏任務(wù))。注意,Node 執(zhí)行宏任務(wù)的方式與瀏覽器不同:在瀏覽器中,我們每次出隊并執(zhí)行一個宏任務(wù);而在 Node 中,我們每次會嘗試清空當(dāng)前階段對應(yīng)宏任務(wù)隊列里的所有任務(wù)(除非達(dá)到系統(tǒng)限制)。
  4. 步驟3開始,會進(jìn)入 3 -> 2 -> 3 -> 2…的循環(huán)。
責(zé)任編輯:姜華 來源: 前端充電寶
相關(guān)推薦

2023-06-11 23:59:59

2024-08-27 11:00:56

單例池緩存bean

2021-09-30 07:59:06

zookeeper一致性算法CAP

2019-08-16 09:41:56

UDP協(xié)議TCP

2021-05-07 07:52:51

Java并發(fā)編程

2022-03-29 08:23:56

項目數(shù)據(jù)SIEM

2022-05-27 08:18:00

HashMapHash哈希表

2023-12-07 09:07:58

2022-08-18 20:45:30

HTTP協(xié)議數(shù)據(jù)

2021-12-13 10:43:45

HashMapJava集合容器

2017-03-30 22:41:55

虛擬化操作系統(tǒng)軟件

2023-09-25 08:32:03

Redis數(shù)據(jù)結(jié)構(gòu)

2023-10-04 00:32:01

數(shù)據(jù)結(jié)構(gòu)Redis

2023-11-07 07:46:02

GatewayKubernetes

2021-09-10 13:06:45

HDFS底層Hadoop

2021-07-28 13:29:57

大數(shù)據(jù)PandasCSV

2023-11-03 08:53:15

StrconvGolang

2021-04-11 08:30:40

VRAR虛擬現(xiàn)實(shí)技術(shù)

2021-10-21 06:52:17

ZooKeeper分布式配置

2021-11-10 07:47:48

Traefik邊緣網(wǎng)關(guān)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

欧美精品高清视频| 99视频有精品| 色悠悠国产精品| 久久久精品高清| av免费在线网站| 国产福利一区在线观看| 欧美国产日韩视频| 中文字幕一区二区久久人妻网站 | 成人在线观看免费播放| 国产精品欧美久久久久一区二区| 国产精品欧美一区二区三区奶水| 人与动物性xxxx| 一区二区三区欧洲区| 亚洲国产一二三| 任我爽在线视频精品一| 97超碰人人草| 国产欧美高清| 日韩中文字幕在线视频播放| 深夜视频在线观看| 亚洲va中文在线播放免费| 国产精品夫妻自拍| 国产综合第一页| 中国老头性行为xxxx| 欧美精品二区| 亚洲图中文字幕| 国产精品久久久久野外| 日韩国产网站| 亚洲成人精品一区二区| 亚洲一卡二卡三卡| 天堂在线中文网| 久久成人久久爱| 久久色精品视频| 日韩黄色一区二区| 欧美一级网址| 日韩欧美国产激情| 97碰在线视频| 美女羞羞视频在线观看| 久久先锋资源网| 福利视频一区二区三区| 一级片视频播放| 国产日韩免费| 色噜噜狠狠色综合网图区| 亚洲の无码国产の无码步美| 亚洲精品乱码日韩| 色婷婷av一区二区三区大白胸 | 欧美91大片| 亚洲美女视频网站| 黄色国产在线视频| 日本在线成人| 欧美精品 日韩| 五月婷婷丁香综合网| 中文字幕高清在线播放| 香蕉成人伊视频在线观看| 久久精品ww人人做人人爽| a级片免费观看| 捆绑变态av一区二区三区| 浅井舞香一区二区| 欧美激情亚洲综合| 欧美午夜影院| 美日韩精品视频免费看| 中国毛片直接看| 99视频精品全国免费| 亚洲香蕉av在线一区二区三区| 蜜臀av粉嫩av懂色av| 日本少妇精品亚洲第一区| 欧美丰满嫩嫩电影| av五月天在线| 88xx成人免费观看视频库 | 在线综合视频网站| 欧美高清电影在线| 久久久午夜精品理论片中文字幕| 精品一区久久久久久| 欧美熟女一区二区| 成人v精品蜜桃久久一区| 丁香五月网久久综合| 国产av一区二区三区| 国产精品77777| 国产精品区一区二区三含羞草| 国产又大又黑又粗| 国产精品一区二区在线观看不卡| 91人人爽人人爽人人精88v| 一区二区三区播放| 国产乱对白刺激视频不卡| 都市激情久久久久久久久久久| 国内精品偷拍视频| 成人免费毛片高清视频| 久久精品成人一区二区三区蜜臀| 免费观看毛片网站| 91色.com| 亚洲精品高清视频| 中文字幕资源网在线观看| 一区二区三区在线观看国产| 欧美国产综合在线| 久久男人天堂| 欧美日韩dvd在线观看| 丰满熟女人妻一区二区三区| 九九视频精品全部免费播放| 久久天天躁狠狠躁夜夜躁2014| 国产一级生活片| 久久精品91| 99c视频在线| a天堂中文在线88| 亚洲无人区一区| 人人干人人干人人| 欧美综合精品| 欧美日韩ab片| 中文字幕 国产精品| 国产成人精品一区二区三区四区| 日韩高清av| 国产盗摄一区二区| 欧美日韩不卡视频| 在线免费观看视频| 国产视频亚洲| 99re国产| h网站久久久| 在线精品亚洲一区二区不卡| 800av在线播放| 亚洲欧洲美洲一区二区三区| 国产精品第10页| 天堂中文网在线| 亚洲已满18点击进入久久| 57pao国产成永久免费视频| 亚洲区小说区| 97精品一区二区三区| 国产成人精品白浆久久69| 中文字幕成人网| www日韩在线观看| 久久人人爽人人爽人人片av不| 久久精品青青大伊人av| 欧美一区二区三区网站| 国产精品一区久久久久| 你懂的网址一区二区三区| 午夜av在线免费观看| 91精品国产综合久久久久久久 | 综合激情久久| 中文字幕亚洲欧美日韩2019| 国产成人精品一区二三区| 国产精品一区在线| 日韩欧美一区二区三区久久婷婷| 欧美a级在线观看| 欧美一区二区成人| 久久精品三级视频| 亚洲在线观看| 国产精品swag| 日本福利在线| 欧美日韩国产免费一区二区| 动漫精品一区二区三区| 黄页网站一区| 97碰碰视频| 黄色片网站在线观看| 在线欧美一区二区| 性欧美精品男男| 美女尤物久久精品| 精品一区日韩成人| 电影在线观看一区| 精品国产麻豆免费人成网站| 免费网站观看www在线观| 九九国产精品视频| 中文字幕一区二区三区最新 | 国产精品男女猛烈高潮激情| 天天操天天干天天爱| 亚洲成a天堂v人片| 久草免费资源站| 国自产拍偷拍福利精品免费一| 亚洲精品日韩激情在线电影| 国产区在线观看| 日韩欧美你懂的| 青娱乐国产在线视频| 国产乱色国产精品免费视频| 日本道在线视频| 伊人久久影院| 午夜精品福利电影| 香蕉视频黄色片| 激情av一区二区| 中文字幕被公侵犯的漂亮人妻| 丝袜国产日韩另类美女| 视频二区一区| 天天综合91| 久久国产精品偷| 国产wwwwwww| 精品久久久久久久久久久久久| 久久午夜夜伦鲁鲁片| 亚洲欧美日韩国产一区二区| 欧美一区二区三区精美影视 | 91超碰在线免费观看| 国产网红在线观看| 亚洲免费精彩视频| 中文字幕福利视频| 亚洲色图.com| 亚洲啪av永久无码精品放毛片| 日韩一级欧洲| 日本欧美色综合网站免费| 欧美一级做a| 欧美xxxx做受欧美.88| 日本午夜在线视频| 欧美老人xxxx18| 国产性生活网站| 91丝袜美腿高跟国产极品老师 | 久久99在线观看| 国产午夜精品视频一区二区三区| 国产精品xxx在线观看| 欧洲精品毛片网站| porn亚洲| 日韩av中文字幕在线| 国产黄色免费视频| 一级中文字幕一区二区| 91精品人妻一区二区三区蜜桃欧美| 免费亚洲一区| 成年在线观看视频| 欧美精品一区二区三区精品| 亚洲a一级视频| а√天堂中文在线资源8| 这里只有视频精品| 成人久久久精品国产乱码一区二区| 欧美性xxxxhd| 欧美在线视频第一页| 欧美激情综合五月色丁香小说| 特黄特色免费视频| 奇米四色…亚洲| 极品美女扒开粉嫩小泬| 久久精品国产大片免费观看| 免费一区二区三区在在线视频| 色婷婷成人网| 欧美又大又粗又长| 羞羞的网站在线观看| 国产一区二区三区在线观看网站| 国产丰满美女做爰| 色狠狠综合天天综合综合| 久久精品视频6| 国产精品久久久久天堂| 国产高清自拍视频| 国产麻豆精品一区二区| 亚洲成熟丰满熟妇高潮xxxxx| 99精品电影| 日本黑人久久| 老汉色老汉首页av亚洲| 91香蕉电影院| av成人亚洲| 日韩免费在线播放| wwwav在线| 日韩视频免费看| 国产福利第一视频在线播放| 亚洲美女久久久| 污污视频在线观看网站| 日韩美一区二区三区| 在线观看免费观看在线| 福利视频导航一区| 天天干天天干天天操| 亚洲午夜精品网| 久久久久久久国产精品毛片| 日韩理论片网站| 中文字幕在线有码| 亚洲欧洲日韩在线| 国产第一页精品| 国产亚洲精品超碰| 欧美激情 亚洲| 成人a免费在线看| 四虎成人在线播放| 久久aⅴ国产欧美74aaa| 久久久久狠狠高潮亚洲精品| 老**午夜毛片一区二区三区| 99久久激情视频| 久久亚洲风情| 久久黄色免费看| 久久精品一区二区国产| 玩弄japan白嫩少妇hd| 亚洲一区二区网站| 男女污污的视频| 免费一区二区视频| a在线观看免费视频| 麻豆精品国产传媒mv男同| 向日葵污视频在线观看| 美女网站色91| 北条麻妃亚洲一区| 国产成人综合视频| 野花视频免费在线观看| 久久综合av免费| 一区二区黄色片| 国产精品日韩成人| 四虎永久免费在线| 精品久久久久久中文字幕| 国产免费观看av| 在线一区二区三区四区五区| 亚洲第一区av| 精品三级在线看| 性感美女福利视频| 伊人亚洲福利一区二区三区| 日韩av中文| 2021国产精品视频| 在线成人视屏| 亚洲xxxxx性| 精品久久ai电影| 性欧美18一19内谢| 国产精品mm| 黄色片一级视频| 精品中文av资源站在线观看| 免费黄色三级网站| 亚洲国产高清在线观看视频| 国模无码国产精品视频| 婷婷中文字幕综合| 欧美一级黄视频| 欧美一区二区久久| 亚洲欧美色视频| 色偷偷噜噜噜亚洲男人| 欧美少妇精品| 91牛牛免费视频| 色天下一区二区三区| 在线观看欧美日韩国产| 黄色正能量网站| 国产精品久久午夜| 日韩一级片av| 色婷婷综合久久久| 国产日产亚洲系列最新| 亚洲欧美在线免费观看| 国内外激情在线| 国产91精品青草社区| 粉嫩一区二区三区在线观看| 涩涩日韩在线| 一区二区亚洲| 天堂中文视频在线| 99热国产精品| 国产一级生活片| 欧美妇女性影城| 免费福利在线视频| 欧美成人小视频| 日本成人一区二区| 蜜桃欧美视频| 欧美特黄a级高清免费大片a级| 日日碰狠狠躁久久躁婷婷| 国产精品88888| 波多野结衣欲乱| 色狠狠综合天天综合综合| 日本一区高清| 久久久久这里只有精品| 97色婷婷成人综合在线观看| 视频一区二区在线| 老鸭窝亚洲一区二区三区| 亚洲少妇一区二区| 亚洲欧洲一区二区在线播放| 国产手机在线视频| 亚洲国产精品人人爽夜夜爽| 3d玉蒲团在线观看| 国产一区二区丝袜| 99热国内精品| 免费看污污网站| 久久久精品tv| 美日韩一二三区| 精品无人区太爽高潮在线播放| 国产美女情趣调教h一区二区| 亚洲伊人久久综合| 日韩在线第七页| 成人综合久久网| 中文字幕在线一区免费| 国产在线观看第一页| 中文字幕亚洲一区二区三区| av日韩电影| 美日韩精品免费| 亚洲一区黄色| 少妇无套高潮一二三区| 91福利视频久久久久| 国产福利在线| 国产精品白丝jk喷水视频一区| 欧美日韩123| 天堂在线资源视频| 国产欧美一二三区| 国产一区二区麻豆| 欧美成年人在线观看| 欧美精品三级在线| 国产人妻互换一区二区| 国产一区不卡在线| 久久久久无码国产精品| 欧美mv和日韩mv的网站| 国产精品伦理| 色中色综合成人| 激情文学综合丁香| 国产一级一片免费播放放a| 亚洲白拍色综合图区| 蜜桃av在线播放| 久久精品国产美女| 久久精品国产99国产精品| 日本a级片视频| 亚洲精品在线电影| 日韩一级二级| 国产精品h视频| 国产99精品视频| 黄色av一区二区| 欧美xxxx18性欧美| 精品资源在线| 超碰网在线观看| 中文字幕佐山爱一区二区免费| 国产高清精品软件丝瓜软件| 色综合视频网站| 成人女性视频| 韩国三级hd中文字幕有哪些| 欧美日韩一二三四五区| 黄色的网站在线观看| 国产女人水真多18毛片18精品| 久久都是精品| 麻豆chinese极品少妇| 亚洲欧美另类人妖|