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

詳解JavaScript運行機制(Event Loop)

原創(chuàng)
開發(fā) 前端
在瀏覽器中,每個渲染進程都有一個主線程,主線程非常繁忙,既要處理DOM,又要計算樣式,還要處理布局,同時還需要處理JavaScript任務以及各種輸入事件。此時我們就需要一個系統(tǒng)來統(tǒng)籌調度這么多不同類型的任務在主線程中有條不紊地執(zhí)行,而這個統(tǒng)籌調度系統(tǒng)就是本文要介紹的事件循環(huán)系統(tǒng)。

【51CTO.com原創(chuàng)稿件】

前言

在瀏覽器中,每個渲染進程都有一個主線程,主線程非常繁忙,既要處理DOM,又要計算樣式,還要處理布局,同時還需要處理JavaScript任務以及各種輸入事件。此時我們就需要一個系統(tǒng)來統(tǒng)籌調度這么多不同類型的任務在主線程中有條不紊地執(zhí)行,而這個統(tǒng)籌調度系統(tǒng)就是本文要介紹的事件循環(huán)系統(tǒng)(Event Loop)。

讀完本文,希望你能明白:

  • 進程與線程的區(qū)別

  • 最新的Chrome瀏覽器包括哪些進程?

  • 瀏覽器與Node的事件循環(huán)(Event Loop)有何區(qū)別?

一、進程與線程

1.概念

我們經常說JavaScript是單線程執(zhí)行的,那到底什么是線程?什么是進程?

一個進程就是一個程序的運行實例。詳細解釋就是,啟動一個程序的時候,操作系統(tǒng)會為該程序創(chuàng)建一塊內存,用來存放代碼、運行中的數(shù)據(jù)和一個執(zhí)行任務的主線程,我們把這樣的一個運行環(huán)境叫進程。

而線程是操作系統(tǒng)能夠進行運算調度的最小單位。線程是不能單獨存在的,它是由進程來啟動和管理的,在進程中使用多線程并行處理能提升運算效率。

我們通過以下這張圖來加深對兩者的理解:

  • 進程好比圖中的工廠,有單獨的專屬自己的工廠資源。當一個進程關閉之后,操作系統(tǒng)會回收進程所占用的內存

  • 線程好比圖中的工人,多個工人在一個工廠中協(xié)作工作,工廠與工人是 1:n的關系。這意味著一個進程由一個或多個線程組成,進程中的任意一線程執(zhí)行出錯,都會導致整個進程的崩潰

  • 工廠的空間是工人們共享的,這意味著一個進程的內存空間是共享的,每個線程都可用這些共享內存

  • 多個工廠之間獨立存在。這意味著進程之間的內容相互隔離

2.多進程與多線程

  • 多進程:在同一個時間里,同一個計算機系統(tǒng)中允許兩個或兩個以上的進程處于運行狀態(tài)。

以最新的 Chrome 瀏覽器為例,我打開掘金編輯文章頁面時,出現(xiàn)以下五個進程:1個網絡進程、1個瀏覽器進程、1個GPU進程以及1個渲染進程,共4個;如果打開的頁面有運行插件的話,還需要再加上1個插件進程(下圖有番茄鬧鐘插件)。

  • 多線程:程序中包含多個執(zhí)行流,即在一個程序中可以同時運行多個不同的線程來執(zhí)行不同的任務,也就是說允許單個程序創(chuàng)建多個并行執(zhí)行的線程來完成各自的任務。

二、最新的 Chrome 進程架構

最新的Chrome瀏覽器包括:1個瀏覽器(Browser)主進程、1個GPU進程、1個網絡(NetWork)進程、多個渲染進程和多個插件進程。

接下來我們介紹下這些進程的功能:

  • 瀏覽器進程。主要負責界面顯示、用戶交互、子進程管理,同時提供存儲等功能。

  • 渲染進程。核心任務是將HTML、CSS 和JavaScript轉換為用戶可以與之交互的網頁,排版引擎Blink和JavaScript引擎V8都是運行在該進程中,默認情況下,Chrome 會為每個Tab標簽創(chuàng)建一個渲染進程。出于安全考慮,渲染進程都是運行在沙箱模式下。渲染進程中主要包含以下線程:主線程(Main thread)、工作線程(Worker thread)、 排版線程 (Compositor thread)和光柵線程(Raster thread)。

  • GPU進程。其實,Chrome剛開始發(fā)布的時候是沒有GPU進程的。而GPU的使用初衷是為了實現(xiàn)3D CSS的效果,只是隨后網頁、Chrome 的UI界面都選擇采用GPU來繪制,這使得GPU成為瀏覽器普遍的需求。最后,Chrome在其多進程架構上也引入了GPU進程。

  • 網絡進程。主要負責頁面的網絡資源加載,之前是作為一個模塊運行在瀏覽器進程里面的,直至最近才獨立出來,成為一個單獨的進程。

  • 插件進程。主要是負責插件的運行,因插件易崩潰,所以需要通過插件進程來隔離,以保證插件進程崩潰不會對瀏覽器和頁面造成影響。

頁面中的大部分任務都是在渲染進程的主線程上執(zhí)行,這些任務包括了:

  • 渲染事件(如解析 DOM、計算布局、繪制);

  • 用戶交互事件(如鼠標點擊、滾動頁面、放大縮小等);

  • JavaScript腳本執(zhí)行事件;

  • 網絡請求完成、文件讀寫完成事件。

那么,如何協(xié)調這些任務有條不紊地在主線程上執(zhí)行呢? 這就需要事件循環(huán)系統(tǒng)(Event Loop)

三、瀏覽器中的 Event Loop

1.什么是Event Loop

通過使用消息隊列,我們實現(xiàn)了線程之間的消息通信。在Chrome中,跨進程之間的任務也是頻繁發(fā)生的,那么如何處理其他進程發(fā)送過來的任務?可以參考下圖(來源極客時間):

 

消息隊列是一種數(shù)據(jù)結構,可以存放要執(zhí)行的任務。它符合隊列“先進先出”的特點,也就是說要添加任務的話,添加到隊列的尾部;要取出任務的話,從隊列頭部去取。

從圖中可以看出,渲染進程專門有一個IO線程用來接收其他進程傳進來的消息,接收到消息之后,會將這些消息組裝成任務發(fā)送給渲染主線程。主線程從"消息隊列"中讀取事件,這個過程是循環(huán)不斷的,所以整個的這種運行機制又稱為Event Loop(事件循環(huán))。

2.同步任務和異步任務

  • 同步任務即可以立即執(zhí)行的任務,例如聲明一個變量或者執(zhí)行一次加法操作等。同步任務屬于宏任務。

  • 異步任務是不會立即執(zhí)行的事件任務。異步任務包括宏任務和微任務。

 

瀏覽器端常見的宏任務包括:setTimeout、setInterval、script(整體代碼)、 I/O 操作、UI 渲染等;

瀏覽器端常見的微任務包括:new Promise().then(回調)、MutationObserver(html5新特性) 等。

3.Event Loop 過程解析

一個完整瀏覽器端的 Event Loop 過程,可以概括為以下階段:

  • 一開始執(zhí)行棧空,我們可以把執(zhí)行棧認為是一個存儲函數(shù)調用的棧結構,遵循先進后出的原則。微任務隊列空,宏任務隊列里有且只有一個 script 腳本(整體代碼)。

  • 全局上下文(script 標簽)被推入執(zhí)行棧,同步代碼執(zhí)行。在執(zhí)行的過程中,會先判斷是同步任務還是異步任務,也會產生新的 macro-task 與 micro-task,它們會分別被推入各自的任務隊列里。同步代碼執(zhí)行完了,script 腳本會被移出 macro 隊列,這個過程本質上是隊列的 macro-task 的執(zhí)行和出隊的過程。

  • 上一步我們出隊的是一個 macro-task,這一步我們處理的是 micro-task。但需要注意的是:當 macro-task 出隊時,任務是一個一個執(zhí)行的;而 micro-task 出隊時,任務是一隊一隊執(zhí)行的。因此,我們處理 micro 隊列這一步,會逐個執(zhí)行隊列中的任務并把它出隊,直到隊列被清空。宏任務隊列可以有多個,微任務隊列只有一個

  • 執(zhí)行渲染操作,更新界面

  • 檢查是否存在 Web worker 任務,如果有,則對其進行處理

  • 上述過程循環(huán)往復,直到兩個隊列都清空

我們總結一下,每一次循環(huán)都是一個這樣的過程:

當某個宏任務執(zhí)行完后,會查看是否有微任務隊列。如果有,先執(zhí)行微任務隊列中的所有任務,如果沒有,會讀取宏任務隊列中排在最前的任務,執(zhí)行宏任務的過程中,遇到微任務,依次加入微任務隊列。棧空后,再次讀取微任務隊列里的任務,依次類推。

接下來我們看道例子來介紹上面流程:

  1. Promise.resolve().then(()=>{ 
  2. console.log('Promise1')   
  3. setTimeout(()=>{ 
  4.   console.log('setTimeout2'
  5. },0) 
  6. }) 
  7. setTimeout(()=>{ 
  8. console.log('setTimeout1'
  9. Promise.resolve().then(()=>{ 
  10.   console.log('Promise2')     
  11. }) 
  12. },0) 

最后輸出結果是Promise1,setTimeout1,Promise2,setTimeout2

  • 一開始執(zhí)行棧的同步任務(這屬于宏任務)執(zhí)行完畢,會去查看是否有微任務隊列,上題中存在(有且只有一個),然后執(zhí)行微任務隊列中的所有任務輸出Promise1,同時會生成一個宏任務 setTimeout2

  • 然后去查看宏任務隊列,宏任務 setTimeout1 在 setTimeout2 之前,先執(zhí)行宏任務 setTimeout1,輸出 setTimeout1

  • 在執(zhí)行宏任務setTimeout1時會生成微任務Promise2 ,放入微任務隊列中,接著先去清空微任務隊列中的所有任務,輸出 Promise2

  • 清空完微任務隊列中的所有任務后,就又會去宏任務隊列取一個,這回執(zhí)行的是 setTimeout2

四、Node 中的 Event Loop

1.Node簡介

Node 環(huán)境下的 Event Loop 與瀏覽器環(huán)境下的 Event Loop并不相同。Node.js 采用 V8 作為js的解析引擎,而I/O處理方面使用了自己設計的libuv,libuv是一個基于事件驅動的跨平臺抽象層,封裝了不同操作系統(tǒng)一些底層特性,對外提供統(tǒng)一的API,事件循環(huán)機制也是它里面的實現(xiàn)(下文會詳細介紹)。注:本文中所介紹Node 環(huán)境中的 Event Loop,是基于node10及其之前版本。

Node.js的運行機制如下:

  • V8引擎解析JavaScript腳本。

  • 解析后的代碼,調用Node API。

  • libuv庫負責Node API的執(zhí)行。它將不同的任務分配給不同的線程,形成一個Event Loop(事件循環(huán)),以異步的方式將任務的執(zhí)行結果返回給V8引擎。

  • V8引擎再將結果返回給用戶。

2.六個階段

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

 

從上圖中,大致看出node中的事件循環(huán)的順序:

外部輸入數(shù)據(jù)-->輪詢階段(poll)-->檢查階段(check)-->關閉事件回調階段(close callback)-->定時器檢測階段(timer)-->I/O事件回調階段(I/O callbacks)-->閑置階段(idle, prepare)-->輪詢階段(按照該順序反復運行)...

  • timers 階段:這個階段執(zhí)行timer(setTimeout、setInterval)的回調

  • I/O callbacks 階段:處理一些上一輪循環(huán)中的少數(shù)未執(zhí)行的 I/O 回調

  • idle, prepare 階段:僅node內部使用

  • poll 階段:獲取新的I/O事件, 適當?shù)臈l件下node將阻塞在這里

  • check 階段:執(zhí)行 setImmediate() 的回調

  • close callbacks 階段:執(zhí)行 socket 的 close 事件回調

注意:上面六個階段都不包括 process.nextTick()(下文會介紹)

接下去我們詳細介紹timerspollcheck這3個階段,因為日常開發(fā)中的絕大部分異步任務都是在這3個階段處理的。

(1) timer

timers 階段會執(zhí)行 setTimeout 和 setInterval 回調,并且是由 poll 階段控制的。 同樣,在 Node 中定時器指定的時間也不是準確時間,只能是盡快執(zhí)行

(2) poll

poll 是一個至關重要的階段,這一階段中,系統(tǒng)會做兩件事情:

1.回到 timer 階段執(zhí)行回調

2.執(zhí)行 I/O 回調

并且在進入該階段時如果沒有設定了 timer 的話,會發(fā)生以下兩件事情:

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

  • 如果 poll 隊列為空時,會有兩件事發(fā)生

    • 如果有 setImmediate 回調需要執(zhí)行,poll 階段會停止并且進入到 check 階段執(zhí)行回調

    • 如果沒有 setImmediate 回調需要執(zhí)行,會等待回調被加入到隊列中并立即執(zhí)行回調,這里同樣會有個超時時間設置防止一直等待下去

當然設定了 timer 的話且 poll 隊列為空,則會判斷是否有 timer 超時,如果有的話會回到 timer 階段執(zhí)行回調。

(3) check階段

setImmediate()的回調會被加入check隊列中,從event loop的階段圖可以知道,check階段的執(zhí)行順序在poll階段之后。 我們先來看個例子:

  1. console.log('start'
  2. setTimeout(() => { 
  3. console.log('timer1'
  4. Promise.resolve().then(function() { 
  5.   console.log('promise1'
  6. }) 
  7. }, 0) 
  8. setTimeout(() => { 
  9. console.log('timer2'
  10. Promise.resolve().then(function() { 
  11.   console.log('promise2'
  12. }) 
  13. }, 0) 
  14. Promise.resolve().then(function() { 
  15. console.log('promise3'
  16. }) 
  17. console.log('end'
  18. //start=>end=>promise3=>timer1=>timer2=>promise1=>promise2 
  • 一開始執(zhí)行棧的同步任務(這屬于宏任務)執(zhí)行完畢后(依次打印出start end,并將2個timer依次放入timer隊列),會先去執(zhí)行微任務(這點跟瀏覽器端的一樣),所以打印出promise3

  • 然后進入timers階段,執(zhí)行timer1的回調函數(shù),打印timer1,并將promise.then回調放入microtask隊列,同樣的步驟執(zhí)行timer2,打印timer2;這點跟瀏覽器端相差比較大,timers階段有幾個setTimeout/setInterval都會依次執(zhí)行,并不像瀏覽器端,每執(zhí)行一個宏任務后就去執(zhí)行一個微任務(關于Node與瀏覽器的 Event Loop 差異,下文還會詳細介紹)。

3.Micro-Task 與 Macro-Task

Node端事件循環(huán)中的異步隊列也是分為macro(宏任務)隊列和 micro(微任務)隊列。

  • Node端常見的 macro-task 比如:setTimeout、setInterval、 setImmediate、script(整體代碼)、 I/O 操作等。

  • Node端常見的 micro-task 比如: process.nextTick、new Promise().then(回調)等。

4.注意點

(1) setTimeout 和 setImmediate

二者非常相似,區(qū)別主要在于調用時機不同。

  • setImmediate 設計在poll階段完成時執(zhí)行,即check階段;

  • setTimeout 設計在poll階段為空閑時,且設定時間到達后執(zhí)行,但它在timer階段執(zhí)行

  1. setTimeout(function timeout () { 
  2. console.log('timeout'); 
  3. },0); 
  4. setImmediate(function immediate () { 
  5. console.log('immediate'); 
  6. }); 
  • 對于以上代碼來說,setTimeout 可能執(zhí)行在前,也可能執(zhí)行在后。

  • 首先 setTimeout(fn, 0) === setTimeout(fn, 1),這是由源碼決定的 進入事件循環(huán)也是需要成本的,如果在準備時候花費了大于 1ms 的時間,那么在 timer 階段就會直接執(zhí)行 setTimeout 回調

  • 如果準備時間花費小于 1ms,那么就是 setImmediate 回調先執(zhí)行了

但當二者在異步i/o callback內部調用時,總是先執(zhí)行setImmediate,再執(zhí)行setTimeout

  1. const fs = require('fs'
  2. fs.readFile(__filename, () => { 
  3.   setTimeout(() => { 
  4.       console.log('timeout'); 
  5.   }, 0) 
  6.   setImmediate(() => { 
  7.       console.log('immediate'
  8.   }) 
  9. }) 
  10. // immediate 
  11. // timeout 

在上述代碼中,setImmediate 永遠先執(zhí)行。因為兩個代碼寫在 IO 回調中,IO 回調是在 poll 階段執(zhí)行,當回調執(zhí)行完畢后隊列為空,發(fā)現(xiàn)存在 setImmediate 回調,所以就直接跳轉到 check 階段去執(zhí)行回調了。

(2) process.nextTick

這個函數(shù)其實是獨立于 Event Loop 之外的,它有一個自己的隊列,當每個階段完成后,如果存在 nextTick 隊列,就會清空隊列中的所有回調函數(shù),并且優(yōu)先于其他 microtask 執(zhí)行。

  1. setTimeout(() => { 
  2. console.log('timer1'
  3. Promise.resolve().then(function() { 
  4.   console.log('promise1'
  5. }) 
  6. }, 0) 
  7. process.nextTick(() => { 
  8. console.log('nextTick'
  9. process.nextTick(() => { 
  10.   console.log('nextTick'
  11.   process.nextTick(() => { 
  12.     console.log('nextTick'
  13.     process.nextTick(() => { 
  14.       console.log('nextTick'
  15.     }) 
  16.   }) 
  17. }) 
  18. }) 
  19. // nextTick=>nextTick=>nextTick=>nextTick=>timer1=>promise1 

五、Node與瀏覽器的 Event Loop 差異

瀏覽器環(huán)境下,microtask的任務隊列是每個macrotask執(zhí)行完之后執(zhí)行。而在Node.js中,microtask會在事件循環(huán)的各個階段之間執(zhí)行,也就是一個階段執(zhí)行完畢,就會去執(zhí)行microtask隊列的任務

接下我們通過一個例子來說明兩者區(qū)別:

  1. setTimeout(()=>{ 
  2.   console.log('timer1'
  3.   Promise.resolve().then(function() { 
  4.       console.log('promise1'
  5.   }) 
  6. }, 0) 
  7. setTimeout(()=>{ 
  8.   console.log('timer2'
  9.   Promise.resolve().then(function() { 
  10.       console.log('promise2'
  11.   }) 
  12. }, 0) 

瀏覽器端運行結果:timer1=>promise1=>timer2=>promise2

瀏覽器端的處理過程如下:

 

Node端運行結果:

要看第一個定時器執(zhí)行完,第二個定時器是否在完成隊列中。

  • 如果是第二個定時器還未在完成隊列中,最后的結果為timer1=>promise1=>timer2=>promise2

  • 如果是第二個定時器已經在完成隊列中,則最后的結果為timer1=>timer2=>promise1=>promise2(下文過程解釋基于這種情況下)

1.全局腳本(main())執(zhí)行,將2個timer依次放入timer隊列,main()執(zhí)行完畢,調用棧空閑,任務隊列開始執(zhí)行;

2.首先進入timers階段,執(zhí)行timer1的回調函數(shù),打印timer1,并將promise1.then回調放入microtask隊列,同樣的步驟執(zhí)行timer2,打印timer2;

3.至此,timer階段執(zhí)行結束,event loop進入下一個階段之前,執(zhí)行microtask隊列的所有任務,依次打印promise1、promise2

Node端的處理過程如下:

六、總結

瀏覽器和Node 環(huán)境下Event Loop有所區(qū)別,主要體現(xiàn)在微任務隊列的執(zhí)行時機不同

  • Node端,microtask 在事件循環(huán)的各個階段之間執(zhí)行

  • 瀏覽器端,microtask 在事件循環(huán)的 macrotask 執(zhí)行完之后執(zhí)行

參考文章與資料

作者介紹

浪里行舟:碩士研究生,專注于前端。個人公眾號:「前端工匠」,致力于打造適合初中級工程師能夠快速吸收的一系列優(yōu)質文章!

【51CTO原創(chuàng)稿件,合作站點轉載請注明原文作者和出處為51CTO.com】

 

責任編輯:龐桂玉 來源: 51CTO
相關推薦

2017-09-14 13:48:20

Vue.js機制應用

2017-09-12 09:50:08

JavaScriptEvent LoopVue.js

2015-11-20 11:20:54

js開發(fā)

2018-03-15 16:45:47

前端JavaScriptthis

2019-05-10 14:00:21

小程序運行機制前端

2009-02-03 14:00:20

PHP運行PHP調用PHP原理

2009-12-11 10:52:37

PHP運行機制

2013-10-24 15:23:40

Event Loop

2010-02-01 17:19:30

C++運行機制

2023-05-26 08:01:01

FacebookVelox機制

2010-01-05 16:10:21

.NET Framew

2019-08-15 10:17:16

Webpack運行瀏覽器

2018-12-26 16:30:09

SQL Server內部運行機制數(shù)據(jù)庫

2010-02-23 10:15:22

WCF運行機制

2012-03-06 10:22:00

程序

2016-12-13 14:12:25

程序機制

2016-12-14 14:41:20

Hello World程序運行機制

2009-10-22 17:10:04

CLR和JRE運行機制

2015-11-16 11:17:30

PHP底層運行機制原理

2010-09-28 11:05:49

jQuery
點贊
收藏

51CTO技術棧公眾號

视频一区二区不卡| 色综合www| 亚洲成人av在线电影| 韩国一区二区三区美女美女秀| 国产成人在线视频观看| 欧美日韩精品一区二区视频| 欧美一级电影网站| 99精品视频播放| 久热国产在线| 91在线国产观看| 国产自摸综合网| 天天综合网久久综合网| 日韩精品午夜| 日韩成人免费视频| www.久久com| 日日夜夜天天综合| 亚洲一区二区三区在线| 亚洲精品中文综合第一页| 丰满人妻一区二区三区无码av| 美女精品网站| 久久久欧美精品| 午夜国产福利视频| 亚洲黄页在线观看| 日韩欧美第一区| 手机视频在线观看| 中文av在线全新| 日韩毛片视频在线看| 久久综合九色综合网站| 性一交一乱一透一a级| 麻豆极品一区二区三区| 日本久久精品视频| 青青操免费在线视频| 欧美淫片网站| www.xxxx精品| 9.1片黄在线观看| 一区二区三区韩国免费中文网站| 精品免费视频.| √天堂资源在线| 久久久久黄色| 在线观看国产日韩| 日韩视频第二页| 成人免费网站观看| 亚洲综合视频在线| 人妻av无码专区| 亚洲七七久久综合桃花剧情介绍| 中文字幕中文乱码欧美一区二区 | 欧美精品一区三区| 国产日韩精品中文字无码| 国产成人一区二区三区影院| 日韩精品黄色网| 亚洲蜜桃精久久久久久久久久久久| 亚洲一区二区三区在线免费 | 日韩一区二区三区中文字幕| www.在线欧美| 久久99国产精品| 人成网站在线观看| 不卡的av网站| 美女黄毛**国产精品啪啪| 日本v片在线免费观看| 久久久综合视频| 欧美日韩综合久久| 成人高清网站| 亚洲欧洲精品天堂一级| 咪咪色在线视频| 50度灰在线| 亚洲国产精品久久人人爱| 欧美 日韩 亚洲 一区| 中文在线免费二区三区| 日本精品免费观看高清观看| 天天操天天摸天天爽| 久久69成人| 欧美一级电影网站| 久久久久久久无码| av在线不卡顿| 欧美巨乳美女视频| 日本在线视频免费| 青青草国产成人99久久| 91久久精品在线| 蜜臀久久精品久久久久| 久久综合色综合88| 在线视频不卡一区二区| 电影k8一区二区三区久久 | 国产精品水嫩水嫩| 日本精品免费视频| 免费高潮视频95在线观看网站| 欧美性极品xxxx娇小| 超碰超碰在线观看| 成人福利一区| 中文字幕国产日韩| 久久国产精品波多野结衣| 午夜亚洲视频| 91免费观看网站| 色综合久久久久久| 国产精品不卡一区二区三区| 丰满少妇大力进入| 777午夜精品电影免费看| 日韩精品资源二区在线| 99久久精品免费视频 | 国产免费观看高清视频| 日本精品另类| 精品剧情在线观看| 国产视频不卡在线| 国产视频一区在线观看一区免费| 国产欧美在线视频| 亚洲精品第五页| 国产精品色在线| 国产免费黄色av| 粉嫩av国产一区二区三区| 日韩精品视频免费| 在线免费日韩av| 久草精品在线观看| 欧美中日韩一区二区三区| 日本中文字幕中出在线| 欧美日韩在线免费视频| 亚洲熟妇一区二区三区| 国产精品v日韩精品v欧美精品网站| 国产不卡av在线| 无码国产精品一区二区色情男同| 亚洲欧洲日韩在线| 国产精品久久a| 在线成人动漫av| 2019av中文字幕| 亚洲av综合色区无码一区爱av| 久久久亚洲高清| 国产欧美日韩网站| jazzjazz国产精品久久| 久久精品国产久精国产一老狼| 天干夜夜爽爽日日日日| gogo大胆日本视频一区| 欧美极品少妇无套实战| 欧美日韩黄色| 久久天天躁日日躁| 亚洲综合精品在线| 国产精品污污网站在线观看| 亚洲人成色77777| 欧美一区 二区| 韩国福利视频一区| 男人天堂综合网| 午夜在线电影亚洲一区| www.四虎在线| 激情婷婷亚洲| 狠狠色综合一区二区| 黄色的视频在线观看| 日韩一区二区三区免费看 | 亚洲av成人片色在线观看高潮 | 日本高清视频免费观看| 亚洲国产精品一区二区久久恐怖片 | 亚洲春色在线视频| 欧美伊人亚洲伊人色综合动图| 最近2019中文免费高清视频观看www99| aaa在线视频| 日本一区二区不卡视频| www.这里只有精品| 国产精品传媒精东影业在线| 成人午夜小视频| 日本孕妇大胆孕交无码| 亚洲第一精品自拍| www.国产一区二区| 久久久噜噜噜久久人人看 | 一本色道婷婷久久欧美| 96sao精品免费视频观看| 久久久久www| 亚洲AV无码精品色毛片浪潮| 亚洲第一激情av| 内射中出日韩无国产剧情| 久久精品人人| 亚洲精品中文字幕在线| 亚洲精品一区二区三区中文字幕| 欧美国产精品日韩| 色哟哟在线观看| 欧美性xxxxxx少妇| 国产一区二区精彩视频| 成人丝袜高跟foot| 国语对白做受xxxxx在线中国| 国产欧美亚洲精品a| 成人情趣片在线观看免费| 第一中文字幕在线| 国产小视频国产精品| 国产女同91疯狂高潮互磨| 亚洲成在人线在线播放| 91麻豆制片厂| 国产精品18久久久久久久久久久久| 久久99久久99精品| 精品国产精品久久一区免费式| 国产欧美一区二区白浆黑人| 韩国日本一区| 亚洲欧美日韩精品久久奇米色影视| 中文字幕人妻色偷偷久久| 亚洲免费在线视频一区 二区| 国产精品扒开腿做爽爽爽a片唱戏| 日韩 欧美一区二区三区| 成人污网站在线观看| 伊甸园亚洲一区| 91探花福利精品国产自产在线| 黄在线观看免费网站ktv| 色999日韩欧美国产| 日韩一卡二卡在线| 69堂精品视频| 国产又大又粗又爽| 亚洲电影中文字幕在线观看| 国产精品麻豆免费版现看视频| 99久久久久久| 黄页网站在线看| 毛片av一区二区三区| 男人添女人下面高潮视频| 婷婷中文字幕一区| 欧美日产一区二区三区在线观看| 综合激情网...| 91精品久久久久久久久久久久久| 筱崎爱全乳无删减在线观看| 欧美精品中文字幕一区| 91最新在线| 亚洲色图日韩av| 色窝窝无码一区二区三区成人网站| 欧美日韩免费观看一区三区| 日本一区二区三区精品| 亚洲一区二区三区四区在线| 手机av在线看| 国产精品人人做人人爽人人添| 给我看免费高清在线观看| 国产成人自拍高清视频在线免费播放| 最近中文字幕一区二区| 久久精品盗摄| 91专区在线观看| 亚洲五月婷婷| 激情成人开心网| 亚洲欧洲中文字幕| 自拍另类欧美| 91欧美在线| 亚洲日本理论电影| 日韩毛片视频| 亚洲精品在线免费看| 国产精品欧美日韩一区| 欧美一级爱爱| 久久av网址| 欧美亚洲丝袜| 亚洲黄色录像| 欧美自拍资源在线| 中文字幕亚洲影视| 欧美精品二区三区四区免费看视频 | 日韩视频一区在线观看| 国产精品玖玖玖| 91精品国产色综合久久不卡蜜臀 | 国产精品一区二区三区四区| 久久精品一卡二卡| 国产在线精品免费| 超级砰砰砰97免费观看最新一期| 韩国三级在线一区| 男生和女生一起差差差视频| 国产成人午夜片在线观看高清观看| 两性午夜免费视频| 国产成人免费av在线| 成人做爰69片免费| 国产成人午夜视频| 国产精品无码在线| 国产视频一区在线观看| 日本污视频网站| 亚洲人吸女人奶水| 精品无码av在线| 精品国产福利在线| 亚洲成人av影片| 欧美日韩卡一卡二| wwwxxxx国产| 亚洲精品午夜精品| 永久免费av在线| 欧美美女18p| 妞干网免费在线视频| 国产精品久久久久国产a级| 欧美videos粗暴| aa成人免费视频| 日本成人中文| 亚洲啪啪av| 韩国亚洲精品| 精品久久久久久无码国产| 久久激情五月激情| 中文字幕在线视频播放| 日本一区二区三区高清不卡| 国产1区2区3区4区| 色94色欧美sute亚洲线路一ni | av网站免费线看精品| 娇妻被老王脔到高潮失禁视频| 18成人在线观看| 91精品国产乱码久久久张津瑜| 欧美写真视频网站| 色丁香婷婷综合久久| 中文字幕亚洲欧美一区二区三区 | 国内视频一区二区| 日韩aaaa| 日韩av在线播放不卡| 奇米777欧美一区二区| 涩视频在线观看| 国产精品水嫩水嫩| 日韩免费一级片| 51午夜精品国产| 日韩有码电影| 欧美劲爆第一页| 成人全视频在线观看在线播放高清| 国产91视觉| 91麻豆精品国产91久久久平台| av动漫在线免费观看| 美女性感视频久久| 国产一级二级在线观看| 自拍偷在线精品自拍偷无码专区| 你懂的国产在线| 精品国产乱码久久| yellow91字幕网在线| 国产精品白嫩美女在线观看| 动漫av一区| 韩国黄色一级大片| 日韩电影网1区2区| 欧美夫妇交换xxx| 亚洲日本在线观看| 中文字幕有码视频| 精品视频久久久| а√天堂中文资源在线bt| 亚洲伊人久久综合| 99国产精品免费视频观看| 老熟妇仑乱视频一区二区| 成人激情小说乱人伦| 欧美成人三级视频| 欧美日韩夫妻久久| jizz亚洲| 国产精品久久久久久久久久免费 | 一区二区三区波多野结衣在线观看| 中文字幕永久在线| 亚洲视频欧美视频| 成人性生活视频| 欧美精品一区二区三区在线四季 | 91pony九色| 国产精品亲子乱子伦xxxx裸| а中文在线天堂| 亚洲性猛交xxxxwww| sese综合| 日韩av电影在线观看| 久久这里有精品15一区二区三区| 亚洲综合自拍网| 欧美色视频日本高清在线观看| 欧美一级性视频| 国产做受高潮69| 欧美人妖在线观看| 日本午夜激情视频| 99v久久综合狠狠综合久久| 日本一二三区视频| 精品一区二区亚洲| 免费电影日韩网站| 色大师av一区二区三区| 免费精品视频最新在线| 日韩av毛片在线观看| 91精品国产综合久久久久久久久久| 成人在线免费看黄| 97人人模人人爽人人喊38tv| 亚洲国产专区| 美女久久久久久久久久| 精品视频一区 二区 三区| 女女色综合影院| 超碰97网站| 国产亚洲精品久久久久婷婷瑜伽| 人人妻人人澡人人爽人人精品| 在线欧美日韩精品| 国精产品一区| 国产精品制服诱惑| 免费在线亚洲欧美| 美女av免费看| 欧美成人a∨高清免费观看| 18video性欧美19sex高清| 欧美日韩另类综合| 紧缚捆绑精品一区二区| 黄色一级片在线| 日韩精品视频在线| 国产精品久久久久久妇女| 久久久天堂国产精品| 99国产精品久久久久久久久久| 国产精品视频123| 日韩视频免费在线| 精品欧美午夜寂寞影院| 欧美一级裸体视频| 亚洲另类在线制服丝袜| 天堂在线视频免费| 国产精品揄拍500视频| 黄色亚洲精品| 夜夜春很很躁夜夜躁| 91精品国产综合久久国产大片| 漫画在线观看av| 一区二区在线观看网站| 99国产精品久| 国产又粗又长视频| 26uuu另类亚洲欧美日本一| 91欧美国产| av在线网站观看| 日韩视频免费直播| 精品成人av| 搞av.com| 亚洲视频在线观看三级| 亚洲av电影一区| 91精品黄色| 免费观看一级特黄欧美大片| 国产成人无码精品| 九九久久久久99精品| 成人国产精品一级毛片视频| 年下总裁被打光屁股sp|