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

給女朋友講React18新特性:Automatic batching

開發 前端
本篇主要講解了「批處理」的意義。還了解了「手動/半自動/自動」三種形式的批處理。最后我們還聊到了批處理的源碼實現邏輯。

[[406703]]

大家好,我是卡頌。

我的女朋友是個鐵憨憨,又菜又愛玩。

鐵憨憨:卡卡,最近好多同事都在聊React18,你給我講講唄?我要你用最通俗的語言把最底層的知識講明白,老娘的時間很寶貴的。

[[406704]]

我:好啊,難得你要學習,這是18所有新特性,你想先看哪個?

說著,我把屏幕轉向她。

鐵憨憨:“這個名字最長,一串英文一看就很厲害”

我一看,她指著Automatic batching(自動批處理)

什么是批處理

鐵憨憨:“批處理,是不是和批發市場搞批發一個意思?”

雖然對這個比喻很無語,但不得不承認:還真挺像!

在React中,開發者通過調用this.setState(或useState的dispatch方法)觸發狀態更新。

狀態更新可能最終反映為視圖更新(取決于是否有DOM變化)。

開發者早已接受一個顯而易見的設定:「狀態」與「視圖」是一一對應的。

但是,讓我們站在React團隊的角度思考一個問題:

  • 從this.setState調用到最終視圖更新,中間需要經過源碼內部的一系列工作。這一系列工作應該是同步還是異步的呢?

如下例子中,a初始狀態為0,當觸發onClick,調用兩次this.setState:

  1. // ...省略無關信息 
  2. state = { 
  3.   a: 0 
  4. onClick() { 
  5.   this.setState({a: 1}); 
  6.   console.log('a is:', this.state.a); 
  7.   this.setState({a: 2}); 
  8. render() { 
  9.   const {a} = this.state; 
  10.   return <p onClick={this.onClick}>{a}</p>; 

如果流程是異步的(即console.log打印a is:0),會有兩個潛在問題:

問題1:中間視圖狀態

當狀態更新互相之間都是異步的,那么例子中頁面上的數字會從0先變為1,再變為2。

顯然更期望的行為是:數字直接從0變為2。

問題2:狀態更新的競爭問題

{a: 1}與{a: 2}的狀態變化誰先反映到視圖更新?

畢竟在異步情況下,即使this.setState({a: 1})先觸發,也可能this.setState({a: 2})的流程先完成。

開發者可不希望用戶點擊時,有時候數字從0變為2,有時候變為1。

鐵憨憨:“好復雜啊,那就改為同步唄,能同時解決這兩個問題,還簡單!”

確實,如果狀態更新都是同步的,那么:

  • 同步流程發生在同一個task(宏任務),不會出現視圖的中間狀態
  • 更新之間有明確的順序,不會出現「競爭問題」

但是,同步流程也意味著當更新發生時,瀏覽器會一直被JS線程阻塞(執行更新流程)。

如果更新流程很復雜(應用很大),或同時觸發很多更新,那么瀏覽器就會掉幀,表現為「瀏覽器卡頓」。

那該怎么辦呢?React團隊給出的解決辦法就是:「批處理」(batchedUpdates)。

  • 批處理:React會嘗試將同一上下文中觸發的更新合并為一個更新

在我們剛才的例子中:

  1. onClick() { 
  2.   this.setState({a: 1}); 
  3.   console.log('a is:', this.state.a); 
  4.   this.setState({a: 2}); 

兩次this.setState改變的狀態會按順序保存下來,最終只會觸發一次狀態更新。

這樣做的好處顯而易見:

  • 合并不必要的更新,減少更新流程調用次數
  • 狀態按順序保存下來,更新時不會出現「競爭問題」
  • 最終觸發的更新是異步流程,減少瀏覽器掉幀可能性

就像到批發市場拉貨。如果老板派幾輛小貨車去,可能由于路上耽擱,先去的車不一定先回(競爭問題)。

還不如提前統計好要拉的貨,派一輛大貨車去,一次拉完了再回(批處理)。

鐵憨憨:“我明白了!不過為什么叫「自動批處理」?難不成像槍一樣還有手動、半自動?”

是的,v18的「批處理」是自動的。

v18之前的React使用半自動「批處理」。

同時,React提供了一個API——unstable_batchedupdates,這就是手動「批處理」。

半自動批處理

要聊「自動批處理」,首先得聊「半自動批處理」。

在v18之前,只有事件回調、生命周期回調中的更新會批處理,比如上例中的onClick。

而在promise、setTimeout等異步回調中不會批處理。

究其原因,讓我們看看批處理源碼(你不需要理解其中變量的意義,這不重要):

  1. export function batchedUpdates<A, R>(fn: A => R, a: A): R { 
  2.   const prevExecutionContext = executionContext; 
  3.   executionContext |= BatchedContext; 
  4.   try { 
  5.     return fn(a); 
  6.   } finally { 
  7.     executionContext = prevExecutionContext; 
  8.     // If there were legacy sync updates, flush them at the end of the outer 
  9.     // most batchedUpdates-like method. 
  10.     if (executionContext === NoContext) { 
  11.       resetRenderTimer(); 
  12.       flushSyncCallbacksOnlyInLegacyMode(); 
  13.     } 
  14.   } 

可以看到,傳入一個回調函數fn,此時會通過「位運算」為代表當前執行上下文狀態的變量executionContext增加BatchedContext狀態。

擁有這個狀態位代表當前執行上下文需要批處理。

在fn執行過程中,其獲取到的全局變量executionContext都會包含BatchedContext。

最終fn執行完后,進入try...finally邏輯,將executionContext恢復為之前的上下文。

曾經React源碼內部,執行onClick時的邏輯類似如下:

  1. batchedUpdates(onClick, e); 

在onClick內部的this.setState中,獲取到的executionContext包含BatchedContext,不會立刻進入更新流程。

等退出該上下文后再統一執行一次更新流程,這就是「半自動批處理」。

鐵憨憨:“既然batchedUpdates是React自動調用的,為啥是「半自動批處理」?”

原因在于batchedUpdates方法是同步調用的。

如果fn有異步流程,比如如下例子:

  1. onClick() { 
  2.   setTimeout(() => { 
  3.     this.setState({a: 3}); 
  4.     this.setState({a: 4}); 
  5.   }) 

那么在真正執行this.setState時batchedUpdates早已執行完,executionContext中已經不包含BatchedContext。

此時觸發的更新不會走批處理邏輯。

所以這種「只對同步流程中的this.setState進行批處理」,只能說是「半自動」。

手動批處理

為了彌補「半自動批處理」的不靈活,ReactDOM中導出了unstable_batchedUpdates方法供開發者手動調用。

比如如上例子,可以這樣修改:

  1. onClick() { 
  2.   setTimeout(() => { 
  3.     ReactDOM.unstable_batchedUpdates(() => { 
  4.       this.setState({a: 3}); 
  5.       this.setState({a: 4}); 
  6.     }) 
  7.   }) 

那么兩次this.setState調用時上下文中全局變量executionContext中會包含BatchedContext。

鐵憨憨:“你這么說我就理解批處理的實現了。不過v18是怎么實現在各種上下文環境都能批處理呢?有點神奇啊!”

[[406705]]

自動批處理

v18實現「自動批處理」的關鍵在于兩點:

  • 增加調度的流程
  • 不以全局變量executionContext為批處理依據,而是以更新的「優先級」為依據

鐵憨憨:“怎么冒出個「優先級」?這是什么鬼?”

我:“那我先給你介紹介紹「更新」以及「優先級」是什么意思吧。”

優先級的意思

調用this.setState后源碼內部會依次執行:

  1. 根據當前環境選擇一個「優先級」
  2. 創造一個代表本次更新的update對象,賦予他步驟1的優先級
  3. 將update掛載在當前組件對應fiber(虛擬DOM)上
  4. 進入調度流程

以如下例子來說:

  1. onClick() { 
  2.   this.setState({a: 3}); 
  3.   this.setState({a: 4}); 

第一次執行this.setState創造的update數據結構如下:

第二次執行this.setState創造的update數據結構如下:

其中lane代表該update的優先級。

在v18,不同場景下觸發的更新擁有不同「優先級」,比如:

  • 如上例子中事件回調中的this.setState會產生同步優先級的更新,這是最高的優先級(lane為1)

為了對比,我們將如上代碼放入setTimeout中:

  1. onClick() { 
  2.   setTimeout(() => { 
  3.     this.setState({a: 3}); 
  4.     this.setState({a: 4}); 
  5.   }) 

第一次執行this.setState創造的update數據結構如下:

第二次執行this.setState創造的update數據結構如下:

lane為16,代表Normal(即一般優先級)。

鐵憨憨:“所以每次調用this.setState會產生update對象,根據調用的場景他會擁有不同的lane(優先級),是吧?”

我:“完全正確!”。

鐵憨憨:“那這和「批處理」有什么關系呢?”

我:“別急,這就是接下來進入調度流程做的事了。”

調度流程

在組件對應fiber掛載update后,就會進入「調度流程」。

試想,一個大型應用,在某一時刻,應用的不同組件都觸發了更新。

那么在不同組件對應的fiber中會存在不同優先級的update。

「調度流程」的作用就是:選出這些update中優先級最高的那個,以該優先級進入更新流程。

讓我們節選部分「調度流程」的源碼:

  1. function ensureRootIsScheduled(root, currentTime) { 
  2.  
  3.   // 獲取當前所有優先級中最高的優先級 
  4.   var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); 
  5.   // 本次要調度的優先級 
  6.   var newCallbackPriority = getHighestPriorityLane(nextLanes);  
  7.    
  8.   // 已經存在的調度的優先級 
  9.   var existingCallbackPriority = root.callbackPriority; 
  10.  
  11.   if (existingCallbackPriority === newCallbackPriority) { 
  12.     return
  13.   } 
  14.   // 調度更新流程 
  15.   newCallbackNode = scheduleCallback(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root)); 
  16.  
  17.   root.callbackPriority = newCallbackPriority; 
  18.   root.callbackNode = newCallbackNode; 

節選后的調度流程大體是:

  1. 獲取當前所有優先級中最高的優先級
  2. 將步驟1的優先級作為本次調度的優先級
  3. 看是否已經存在一個調度
  4. 如果已經存在調度,且和當前要調度的優先級一致,則return
  5. 不一致的話就進入調度流程

可以看到,調度的最終目的是在一定時間后執行performConcurrentWorkOnRoot,正式進入更新流程。

還是以上面的例子來說:

  1. onClick() { 
  2.   this.setState({a: 3}); 
  3.   this.setState({a: 4}); 

第一次調用this.setState,進入「調度流程」后,不存在existingCallbackPriority。

所以會執行調度:

  1. newCallbackNode = scheduleCallback(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root)); 

第二次調用this.setState,進入「調度流程」后,已經存在existingCallbackPriority,即第一次調用產生的。

此時比較兩者優先級:

  1. if (existingCallbackPriority === newCallbackPriority) { 
  2.   return

由于兩個更新都是在onClick中觸發,擁有同樣優先級,所以return。

按這個邏輯,即使多次調用this.setState,如:

  1. onClick() { 
  2.   this.setState({a: 3}); 
  3.   this.setState({a: 4}); 
  4.   this.setState({a: 5}); 
  5.   this.setState({a: 6}); 

只有第一次調用會執行調度,后面幾次執行由于優先級和第一次一致會return。

當一定時間過后,第一次調度的回調函數performConcurrentWorkOnRoot會執行,進入更新流程。

由于每次執行this.setState都會創建update并掛載在fiber上。

所以即使只執行一次更新流程,還是能將狀態更新到最新。

這就是以「優先級」為依據的「自動批處理」邏輯。

總結

通過本次講解,女朋友不僅學習了「批處理」的意義。還了解了「手動/半自動/自動」三種形式的批處理。

最后我們還聊到了批處理的源碼實現邏輯。

 

責任編輯:姜華 來源: 魔術師卡頌
相關推薦

2021-06-22 07:45:57

React18startTransiReact

2021-11-01 19:49:55

React組件模式

2021-06-16 06:05:25

React18React

2020-10-25 08:22:28

V8 引擎JavaScript回調函數

2021-11-29 06:05:31

React組件前端

2021-10-21 08:31:31

Spring循環依賴面試

2019-03-12 09:43:14

反向代理正向代理服務器

2021-03-05 17:06:53

全排列組合子集

2020-03-16 14:08:59

線程熔斷限流

2019-04-09 09:40:23

2023-03-21 08:31:13

ReconcilerFiber架構

2022-03-16 17:01:35

React18并發的React組件render

2022-03-30 14:22:55

ReactReact18并發特性

2019-10-09 10:45:16

云計算Web互聯網

2021-09-14 12:00:11

VR字節跳動

2022-04-27 07:37:42

ReactReact18

2021-03-11 16:45:29

TCP程序C語言

2020-10-19 13:01:31

刪庫程序員思科

2019-04-26 14:46:18

GitGitHub局域網

2019-04-19 09:48:53

樂觀鎖悲觀鎖數據庫
點贊
收藏

51CTO技術棧公眾號

国精产品一区二区三区| 亚洲国内在线| 国产小视频在线免费观看| 国产美女撒尿一区二区| 一区二区三区中文字幕在线观看| 国内久久婷婷综合| 欧美在线观看一区二区| 午夜久久资源| 精品国产av 无码一区二区三区| 你懂的国产精品永久在线| 精品人在线二区三区| 激情伊人五月天| 国产高清视频在线观看| 精品制服美女久久| 国内久久久精品| 黄色国产在线播放| 亚洲国产欧美国产第一区| 精品久久久一区二区| 亚洲在线播放电影| 亚洲精品字幕在线观看| 日日骚欧美日韩| 欧美精品性视频| 性久久久久久久久久| av网站大全在线| 久久只精品国产| 91免费在线观看网站| 波多野结衣视频网站| 91精品啪在线观看国产18| 亚洲国产私拍精品国模在线观看| 嫩草影院国产精品| av美女在线观看| 国产精品福利一区二区三区| 国产区二精品视| 亚洲天堂一二三| 欧美日韩18| 中文字幕在线精品| 娇妻被老王脔到高潮失禁视频| 日韩伦理一区二区三区| 欧美成人官网二区| 青娱乐国产精品视频| 久久日本片精品aaaaa国产| 欧美极品aⅴ影院| 国产日韩欧美一区二区三区四区| 亚洲图片视频小说| 久久一区激情| 午夜精品久久久久久久久久久久| 日韩精品一区二区三区在线视频| 美女少妇全过程你懂的久久 | 色婷婷狠狠综合| 日韩在线视频在线| 韩国av网站在线| 中文字幕免费观看一区| 女人一区二区三区| 色偷偷在线观看| 岛国av在线一区| 91免费在线视频| 国产又大又长又粗| 美女视频黄 久久| 国产精品 欧美在线| 国产成人啪精品午夜在线观看| 久久久久亚洲| xxxx性欧美| 999精品久久久| 久久在线播放| 精品国产一区二区三区久久久| 国产精品天天干| 红桃成人av在线播放| 亚洲国产精品va在线| 亚洲色偷偷色噜噜狠狠99网| 精品一区二区三区中文字幕 | 在线观看久久av| 亚洲精品一区二区三区影院忠贞| 亚洲春色h网| 亚洲人成在线观看| 国产三级av在线播放| 国产伦一区二区三区| 亚洲人成电影网站色xx| 在哪里可以看毛片| 国产真实有声精品录音| 一区二区欧美久久| 午夜剧场免费在线观看| 欧美99在线视频观看| 欧美精品videos另类日本| 国产在线免费视频| 国产精品久久| 97色在线观看免费视频| 少妇一级淫片免费放中国| 午夜综合激情| 欧美一区二区色| 夜夜躁日日躁狠狠久久av| 久草在线在线精品观看| 成人自拍视频网站| 无码国产精品一区二区免费16| 久久久蜜桃精品| 一区二区不卡视频| 麻豆av在线导航| 亚洲一区在线视频| 99热自拍偷拍| 九七影院97影院理论片久久 | 91免费国产在线观看| 日韩视频专区| 91福利国产在线观看菠萝蜜| 亚洲午夜视频在线| 男人舔女人下面高潮视频| 成人精品高清在线视频| 欧美一区二区免费视频| 亚洲欧美在线不卡| 午夜av一区| 国内自拍欧美激情| 欧美一区二区三区久久久| 麻豆成人在线观看| 114国产精品久久免费观看| 天天干天天插天天操| 国产欧美日韩综合精品一区二区| 天天爱天天做天天操| 性国裸体高清亚洲| 欧美亚洲尤物久久| 精品伦一区二区三区| 欧美日一区二区| 欧美激情18p| 中文字幕在线视频免费| 91精品国产吴梦梦| 成人在线播放免费观看| 欧美自拍丝袜亚洲| 性久久久久久久久久久| 在线观看国产精品入口| 国产成人精品日本亚洲| 亚洲av成人精品一区二区三区在线播放 | 一区二区三区中文字幕| 国产三级日本三级在线播放| 人人精品亚洲| 久久久久久国产精品久久| 国产伦精品一区二区三区四区| 国产三级精品三级| 国产a级一级片| 北条麻妃一区二区三区在线观看 | 免费人成在线不卡| 日韩免费毛片| 国产超碰精品| 亚洲性av在线| 日本a级c片免费看三区| 91丨porny丨在线| 少妇无码av无码专区在线观看| 日本精品一区二区三区在线观看视频| 日韩网站免费观看| 国产精品视频在线观看免费| 中文字幕一区二区三区在线观看 | 亚洲精品第一| 久久韩剧网电视剧| 99久久免费国产精精品| 综合av第一页| 日本成人在线免费| 亚洲成人资源| 欧美大陆一区二区| 天天免费亚洲黑人免费| 最近2019免费中文字幕视频三| 伊人精品在线视频| 亚洲蜜臀av乱码久久精品蜜桃| www.久久com| 激情综合久久| 欧美日韩国产三区| 国a精品视频大全| 手机福利在线| 欧美日韩在线播放三区四区| 黑人と日本人の交わりビデオ| 激情av综合网| 国产一区二区三区小说| 亚洲欧洲美洲国产香蕉| 国产精品日韩av| av网站网址在线观看| 亚洲国产欧美日韩精品| 久草热在线观看| 亚洲视频网在线直播| 香蕉久久久久久av成人| 亚洲一区一卡| 国产奶头好大揉着好爽视频| 嗯用力啊快一点好舒服小柔久久| 欧美一级免费视频| 亚洲欧美视频一区二区| 精品国产一区久久| 日本免费精品视频| 亚洲人精品午夜| av鲁丝一区鲁丝二区鲁丝三区| 日韩精品一卡二卡三卡四卡无卡| 一区二区三区视频在线播放| а√中文在线天堂精品| 国产精品成人久久久久| 国产黄a三级三级三级av在线看 | 懂色av一区二区三区在线播放| 亚洲综合电影| 操日韩av在线电影| 免费在线观看污视频| 91精品蜜臀在线一区尤物| 在线观看国产亚洲| 成人免费一区二区三区视频 | 中文字幕亚洲影视| 91免费国产视频| jk漫画禁漫成人入口| 乱亲女秽乱长久久久| 黄色片在线看| 精品久久久久久久人人人人传媒| 亚洲图片欧美日韩| 亚洲综合色自拍一区| 国产一区一区三区| 国产免费美女视频| av一区二区久久| 精品国产依人香蕉在线精品| 黑人乱码一区二区三区av| 在线观看视频一区| 国产中文字幕免费| 日韩一区在线看| 欧美特级黄色录像| av福利精品导航| 精品人妻人人做人人爽夜夜爽| 日韩电影免费在线观看网站| 成年人看的毛片| 婷婷亚洲最大| 日本一区高清在线视频| 农村少妇一区二区三区四区五区| 成人性生交大片免费看视频直播 | 国语自产精品视频在线看| 在线观看麻豆| 亚洲一区二区黄| 污视频网站免费观看| 日韩欧美亚洲国产另类| 中文字幕资源网| 日韩欧美在线观看视频| 国产午夜精品无码一区二区| 有码一区二区三区| 91麻豆精品成人一区二区| 国产人久久人人人人爽| 一色道久久88加勒比一| 久久影院电视剧免费观看| 私密视频在线观看| 不卡欧美aaaaa| 岛国av免费观看| 成人小视频免费观看| 久久久无码人妻精品无码| 国产高清视频一区| 亚洲成人福利视频| 国产精品综合二区| 99久久99精品| 国产剧情一区二区| 国产伦精品一区二区三区妓女下载| 狠狠狠色丁香婷婷综合激情 | 国产精品15p| 国产二区一区| 久久精品国产一区| 波多野结衣家庭教师| 国产精品久久午夜夜伦鲁鲁| 亚洲国产av一区| 久久久久9999亚洲精品| 中文乱码人妻一区二区三区视频| 成人教育av在线| 制服丝袜第一页在线观看| 成人午夜视频在线观看| 性活交片大全免费看| 99精品视频在线免费观看| 成人在线视频免费播放| 97久久精品人人爽人人爽蜜臀| 中文字幕永久免费| 99久久精品免费精品国产| 成人免费看aa片| 国产区在线观看成人精品 | 国产精品成人网| 性生交大片免费全黄| 一区二区三区四区不卡视频| 国产一级片免费看| 欧美视频在线观看免费网址| 男人天堂视频在线| 欧美日本国产视频| 国产主播第一页| 欧美一级艳片视频免费观看| 亚洲免费成人网| 亚洲女成人图区| 国产原创在线观看| 性欧美激情精品| 欧美一级二级视频| 草莓视频一区| 亚洲三级精品| 91手机视频在线| 99热免费精品在线观看| youjizzxxxx18| 国产91丝袜在线播放九色| 亚洲永久无码7777kkk| 成人一级视频| 日韩av在线资源| 丁香婷婷在线| 欧美黑人xxxx| 成人亚洲网站| 国产在线播放一区二区| 成人一区二区| 欧美精品久久久久久久自慰| 免费在线观看一区二区三区| 亚洲成年人av| 中文字幕在线观看一区二区| 日韩女同强女同hd| 91精品国产日韩91久久久久久| 天天干天天做天天操| 久久精品国产久精国产思思| 亚洲啊v在线| 97超碰在线播放| 日韩精品一区二区久久| www.日本在线播放| 精品一区二区国语对白| 免费毛片视频网站| 亚洲一区免费在线观看| 在线播放精品视频| 精品在线观看国产| 男女在线观看视频| 国产日韩欧美视频| 免费成人网www| 国产精品久久久久7777| 久久国产高清| 日韩中文字幕a| 久久久久国产成人精品亚洲午夜 | 在线免费观看黄色网址| 91爱视频在线| 亚洲国产欧美在线观看| 黄色网址在线免费看| 免费观看在线色综合| 成人午夜剧场视频网站| 亚洲电影在线免费观看| jlzzjlzzjlzz亚洲人| 久久精品国产清自在天天线| 成人免费av电影| 日本午夜精品电影| 亚洲一区二区三区免费在线观看| 欧美做受高潮中文字幕| 一区二区三区欧美亚洲| 99热精品在线播放| 久久精视频免费在线久久完整在线看| 成人在线视频播放| 日韩欧美电影一区二区| 久久精品女人天堂| 一区二区黄色片| 日韩精品麻豆| 国产在线精品一区二区中文| 欧美日韩第一区| 精人妻一区二区三区| 亚洲国产一区二区在线播放| 高h放荡受浪受bl| 欧美激情手机在线视频| 91久久精品无嫩草影院| 久久福利一区二区| 国产不卡免费视频| 国产精品成人免费一区二区视频| 精品国产一二三| 9lporm自拍视频区在线| 精品欧美国产| 西西人体一区二区| 三级网站在线免费观看| 欧洲av一区二区嗯嗯嗯啊| 在线看黄色av| 91在线视频免费| 亚洲欧美综合| 日本在线不卡一区二区| 大伊人狠狠躁夜夜躁av一区| 黄色的视频在线免费观看| 国产精品久久久91| 99欧美视频| 四虎成人免费视频| 狠狠躁夜夜躁人人爽天天天天97 | 国产日韩一区二区在线| 日本一区二区综合亚洲| 国产尤物视频在线观看| 欧美多人爱爱视频网站| 老司机凹凸av亚洲导航| 黄色一级二级三级| 亚洲视频一区二区在线| 男人天堂一区二区| 国产成人亚洲综合91精品| 欧美电影免费| av天堂一区二区| 一本大道久久a久久综合婷婷| 中文日本在线观看| 国产女人水真多18毛片18精品| 久久国产精品毛片| 99精品中文字幕| 亚洲国产免费av| 成人一级视频| 久久久久免费看黄a片app| 国产欧美一区二区三区网站| 国内老熟妇对白hdxxxx| 欧美一级电影在线| 91精品蜜臀一区二区三区在线| 亚洲色图14p| 欧美日韩久久一区二区| av资源在线播放| 亚洲人一区二区| 成人国产精品免费观看动漫| 中国精品一区二区| 久久久久久久久91| 日韩黄色大片| 亚洲精品女人久久久| 3d动漫精品啪啪一区二区竹菊| 蜜臀久久精品| 992tv快乐视频| 国产精品女同互慰在线看| 后进极品白嫩翘臀在线视频|