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

代碼越寫越亂?那是因為你沒用責任鏈

開發 前端
代碼中的 httpErrorHandler 會接收 API 的響應錯誤,并對錯誤的狀態碼做不同的處理,所以代碼中需要很多 if(或者 switch)判斷當前需要要執行什么,當你要對新的錯誤添加處理代碼時,就必須要到 httpErrorHandler 中修改代碼。

 [[396382]]

目的

在開始學習責任鏈之前,先看一下在開發中常見的問題。下面是前端用來處理 API 錯誤碼的代碼:

 

  1.  const httpErrorHandler = (error) => { 
  2.    const errorStatus = error.response.status; 
  3.    if (errorStatus === 400) { 
  4.      console.log('你是不是提交了什么奇怪的東西?'); 
  5.    } 
  6.     
  7.    if (errorStatus === 401) { 
  8.      console.log('需要先登陸!'); 
  9.    } 
  10.     
  11.    if (errorStatus === 403) { 
  12.      console.log('是不是想偷摸干壞事?'); 
  13.    } 
  14.     
  15.    if (errorStatus === 404) { 
  16.      console.log('這里什么也沒有...'); 
  17.    } 
  18. }; 

當然實際項目中不可能只有一行 console,這是為了說明原理的簡化版。

代碼中的 httpErrorHandler 會接收 API 的響應錯誤,并對錯誤的狀態碼做不同的處理,所以代碼中需要很多 if(或者 switch)判斷當前需要要執行什么,當你要對新的錯誤添加處理代碼時,就必須要到 httpErrorHandler 中修改代碼。

雖然免不了要經常修改代碼,但是這樣做可能會導致幾個問題,下面根據 SOLID 的 單一職責(Single responsibility)和開放封閉(open/close)這兩個原則來說明:

單一職責(Single responsibility)

簡單的說,單一職責就是只做一件事情。而前面的 httpErrorHandler 方法以使用的角度來說,是把錯誤對象交給它,讓它按照錯誤碼做對應的處理??瓷先ズ孟袷窃谧?ldquo;錯誤處理”這個單一的事情,但是從實現的角度上來說,它把不同錯誤的處理邏輯全部寫在了 httpErrorHandler 中,這就會導致可能在只想要修改對錯誤碼為 400 的邏輯時,但是不得不閱讀一大堆不相關的代碼。

開放封閉原則(open/close)

開放封閉原則是指對已經寫好的核心邏輯就不要再去改動,但同時要能夠因需求的增加而擴充原本的功能,也就是開放擴充功能,同時封閉修改原本正確的邏輯。再回過頭來看 httpErrorHandler,如果需要增加一個對錯誤碼 405 的處理邏輯(要擴充新功能),那就需要修改 httpErrorHandler 中的代碼(修改原本正確的邏輯),這也很容易造成原來正確執行的代碼出錯。

既然 httpErrorHandler 破綻這么多,那該怎么辦?

解決問題

分離邏輯

先讓 httpErrorHandler 符合單一原則。首先把每個錯誤的處理邏輯分別拆成方法:

 

  1. const response400 = () => { 
  2.   console.log('你是不是提交了什么奇怪的東西?'); 
  3. }; 
  4.  
  5. const response401 = () => { 
  6.   console.log('需要先登陸!'); 
  7. }; 
  8.  
  9. const response403 = () => { 
  10.   console.log('是不是想偷摸干壞事?'); 
  11. }; 
  12.  
  13. const response404 = () => { 
  14.   console.log('這里什么也沒有...'); 
  15. }; 
  16.  
  17. const httpErrorHandler = (error) => { 
  18.   const errorStatus = error.response.status; 
  19.   if (errorStatus === 400) { 
  20.     response400(); 
  21.   } 
  22.     
  23.   if (errorStatus === 401) { 
  24.     response401(); 
  25.   } 
  26.     
  27.   if (errorStatus === 403) { 
  28.     response403(); 
  29.   } 
  30.     
  31.   if (errorStatus === 404) { 
  32.     response404(); 
  33.   } 
  34. }; 

雖然只是把每個區塊的邏輯拆成方法,但這已經可以讓我們在修改某個狀態碼的錯誤處理時,不用再到 httpErrorHandler 中閱讀大量的代碼了。

僅僅是分離邏輯這個操作同時也讓 httpErrorHandler 符合了開放封閉原則,因為在把錯誤處理的邏輯各自拆分為方法的時候,就等于對那些已經完成的代碼進行了封裝,這時當需要再為 httpErrorHandler 增加對 405 的錯誤處理邏輯時,就不會影響到其他的錯誤處理邏輯的方法(封閉修改),而是另行創建一個新的 response405 方法,并在 httpErrorHandler 中加上新的條件判斷就行了(開放擴充新功能)。

現在的 httpErrorHandler 其實是策略模式(strategy pattern),httpErrorHandler 用了統一的接口(方法)來處理各種不同的錯誤狀態,在本文的最后會再次解釋策略模式和責任鏈之間的區別。

責任鏈模式(Chain of Responsibility Pattern)責任鏈的實現

原理很簡單,就是把所有方法串起來一個一個執行,并且每個方法都只做自己要做的事就行了,例如 response400 只在遇到狀態碼為 400 的時候執行,而 response401 只處理 401 的錯誤,其他方法也都只在自己該處理的時候執行。每個人各司其職,就是責任鏈。

接下來開始實現。

增加判斷

根據責任鏈的定義,每個方法都必須要知道當前這件事是不是自己應該處理的,所以要把原本在 httpErrorHandler 實現的 if 判斷分散到每個方法中,變成由內部控制自己的責任:

 

  1. const response400 = (error) => { 
  2.   if (error.response.status !== 400) return
  3.   console.log('你是不是提交了什么奇怪的東西?'); 
  4. }; 
  5.  
  6. const response401 = (error) => { 
  7.   if (error.response.status !== 401) return
  8.   console.log('需要先登陸!'); 
  9. }; 
  10.  
  11. const response403 = (error) => { 
  12.   if (error.response.status !== 403) return
  13.   console.log('是不是想偷摸干壞事?'); 
  14. }; 
  15.  
  16. const response404 = (error) => { 
  17.   if (error.response.status !== 404) return
  18.   console.log('這里什么也沒有...'); 
  19. }; 
  20.  
  21. const httpErrorHandler = (error) => { 
  22.   response400(error); 
  23.   response401(error); 
  24.   response403(error); 
  25.   response404(error); 
  26. }; 

把判斷的邏輯放到各自的方法中之后,httpErrorHandler 的代碼就精簡了很多,也去除了所有在 httpErrorHandler 中的邏輯,現在httpErrorHandler 只需要按照順序執行 response400 到 response404 就行了,反正該執行就執行,不該執行的也只是直接 return 而已。

實現真正的責任鏈

雖然只要重構到上一步,所有被分拆的錯誤處理方法都會自行判斷當前是不是自己該做的,但是如果你的代碼就這樣了,那么將來看到 httpErrorHandler 的其他人只會說:

這是什么神仙代碼?API 一遇到錯誤就執行所有錯誤處理?

因為他們不知道在每個處理方法里面還有判斷,也許過一段時間之后你自己也會忘了這事,因為現在的 httpErrorHandler 看起來就只是從 response400 到 response404,即使我們知道功能正確,但完全看不出是用了責任鏈。

那到底怎樣才能看起來像是個鏈呢?其實你可以直接用一個數字記錄所有要被執行的錯誤處理方法,并通過命名告訴將來看到這段代碼的人這里是責任鏈:

 

  1. const httpErrorHandler = (error) => { 
  2.   const errorHandlerChain = [ 
  3.     response400, 
  4.     response401, 
  5.     response403, 
  6.     response404 
  7.   ]; 
  8.   errorHandlerChain.forEach((errorHandler) => { 
  9.     errorHandler(error); 
  10.   }); 
  11. }; 

優化執行

這樣一來責任鏈的目的就有達到了,如果像上面代碼中用 forEach 處理的話,那當遇到 400 錯誤時,實際上是不需要執行后面的 response401 到 response404 的。

所以還要在每個錯誤處理的方法中加上一些邏輯,讓每個方法可以判斷,如果是遇到自己處理不了的事情,就丟出一個指定的字符串或布爾值,接收到之后就再接著執行下一個方法,但如果該方法可以處理,則在處理完畢之后直接結束,不需要再繼續把整個鏈跑完。

 

  1. const response400 = (error) => { 
  2.   if (error.response.status !== 400) return 'next'
  3.   console.log('你是不是提交了什么奇怪的東西?'); 
  4. }; 
  5.  
  6. const response401 = (error) => { 
  7.   if (error.response.status !== 401) return 'next'
  8.   console.log('需要先登陸!'); 
  9. }; 
  10.  
  11. const response403 = (error) => { 
  12.   if (error.response.status !== 403) return 'next';; 
  13.   console.log('是不是想偷摸干壞事?'); 
  14. }; 
  15.  
  16. const response404 = (error) => { 
  17.   if (error.response.status !== 404) return 'next';; 
  18.   console.log('這里什么都沒有...'); 
  19. }; 

如果鏈中某個節點執行結果為 next,則讓下后面的方法繼續處理:

 

  1. const httpErrorHandler = (error) => { 
  2.   const errorHandlerChain = [ 
  3.     response400, 
  4.     response401, 
  5.     response403, 
  6.     response404 
  7.   ]; 
  8.    
  9.   for(errorHandler of errorHandlerChain) { 
  10.     const result = errorHandler(error); 
  11.     if (result !== 'next') break; 
  12.   }; 
  13. }; 

封裝責任鏈的實現

現在責任鏈已經實現完成了,但是判斷要不要給下一個方法的邏輯(判斷 result !== 'next') ,卻暴露在外面,這也許會導致項目中每個鏈的實現方法都會不一樣,其他的鏈有可能是判斷 nextSuccessor 或是 boolean,所以最后還需要封裝一下責任鏈的實現,讓團隊中的每個人都可以使用并且遵守項目中的規范。

責任鏈需要:

  1. 當前的執行者。
  2. 下一個的接收者。
  3. 判斷當前執行者執行后是否需要交由下一個執行者。

所以封裝成類以后應該是這樣:

 

  1. class Chain { 
  2.   constructor(handler) { 
  3.     this.handler = handler; 
  4.     this.successor = null
  5.   } 
  6.  
  7.   setSuccessor(successor) { 
  8.     this.successor = successor; 
  9.     return this; 
  10.   } 
  11.  
  12.   passRequest(...args) { 
  13.     const result = this.handler(...args); 
  14.     if (result === 'next') { 
  15.       return this.successor && this.successor.passRequest(...args); 
  16.     } 
  17.     return result; 
  18.   } 

用 Chain 創建對象時需要將當前的職責方法傳入并設置給 handler,并且可以在新對象上用 setSuccessor 把鏈中的下一個對象指定給 successor,在 setSuccessor 里返回代表整條鏈的 this,這樣在操作的時候可以直接在 setSuccessor 后面用 setSuccessor 設置下一個接收者。

最后,每個通過 Chain 產生的對象都會有 passRequest 來執行當前的職責方法,…arg 會把傳入的所有參數變成一個數組,然后一起交給 handler 也就是當前的職責方法執行,如果返回的結果 result 是 next 的話,就去判斷有沒有指定 sucessor 如果有的話就繼續執行,如果 result 不是 next,則直接返回 result。

有了 Chain 后代碼就會變成:

 

  1. const httpErrorHandler = (error) => { 
  2.   const chainRequest400 = new Chain(response400); 
  3.   const chainRequest401 = new Chain(response401); 
  4.   const chainRequest403 = new Chain(response403); 
  5.   const chainRequest404 = new Chain(response404); 
  6.  
  7.   chainRequest400.setSuccessor(chainRequest401); 
  8.   chainRequest401.setSuccessor(chainRequest403); 
  9.   chainRequest403.setSuccessor(chainRequest404); 
  10.  
  11.   chainRequest400.passRequest(error); 
  12. }; 

這時就很有鏈的感覺了,大家還可以再繼續根據自己的需求做調整,或是也不一定要使用類,因為設計模式的使用并不需要局限于如何實現,只要有表達出該模式的意圖就夠了。

責任鏈的優缺點

優點:

符合單一職責,使每個方法中都只有一個職責。

符合開放封閉原則,在需求增加時可以很方便的擴充新的責任。

使用時候不需要知道誰才是真正處理方法,減少大量的 if 或 switch 語法。

缺點:

團隊成員需要對責任鏈存在共識,否則當看到一個方法莫名其妙的返回一個 next 時一定會很奇怪。

出錯時不好排查問題,因為不知道到底在哪個責任中出的錯,需要從鏈頭開始往后找。

就算是不需要做任何處理的方法也會執行到,因為它在同一個鏈中,文中的例子都是同步執行的,如果有異步請求的話,執行時間也許就會比較長。

與策略模式的不同

在前面我還提到過策略模式,先說說兩個模式之間的相似處,那就是都可以替多個同一個行為(response400、response401 等)定義一個接口(httpErrorHandler),而且在使用時不需要知道最后是誰執行的。在實現上策略模式比較簡單。

由于策略模式直接用 if 或 switch 來控制誰該做這件事情,比較適合一個蘿卜一個坑的狀況。而策略模式雖然在例子中也是針對錯誤的狀態碼做各自的事,都在不歸自己管的時候直接把事交給下一位處理,但是在責任鏈中的每個節點仍然可以在不歸自己管的時候先做些什么,然后再交給下個節點:

 

  1. const response400 = (error) => { 
  2.   if (error.response.status !== 400) { 
  3.     // 先做點什么... 
  4.     return 'next'
  5.   } 
  6.   console.log('你是不是提交了什么奇怪的東西?'); 
  7. }; 

那在什么場景下使用呢?

 

 

 

[[396383]]

 

比如在離職時需要走一個簽字流程:你自己、你的 Leader 還有人資都需要做簽字這件事,所以責任鏈就可以把這三個角色的簽字過程串成一個流程,每個人簽過后都會交給下面一位,一直到人資簽完后才完成整個流程。而且如果通過責任鏈處理這個流程,不論之后流程怎樣變動或增加,都有辦法進行彈性處理。

上面的需求是策略模式所無法勝任的。

責任編輯:華軒 來源: 前端先鋒
相關推薦

2022-07-29 08:40:20

設計模式責任鏈場景

2025-02-06 07:30:32

2021-09-06 18:54:58

Java代碼表達式

2021-01-18 11:09:42

區塊鏈比特幣工具

2018-07-31 14:03:09

JVM內存數據

2019-12-26 14:50:36

ORDER BY數據庫排序函數

2022-12-12 09:46:49

Kubernetes容器

2025-07-14 00:00:00

2021-06-09 10:59:13

數字化轉型CIO數字化

2021-05-13 09:27:13

JavaThreadLocal線程

2018-05-05 08:54:24

2015-05-13 09:52:29

程序員代碼

2023-06-26 07:05:12

IntelWindows電腦

2021-02-22 11:00:39

機器學習人工智能AI

2018-04-24 10:29:40

2009-11-26 10:15:00

IT職場

2021-12-23 23:04:54

手機蘋果國產

2015-04-14 10:39:09

iWatch蘋果

2025-11-04 08:43:00

2021-06-15 06:56:17

安卓系統應用手機卡頓
點贊
收藏

51CTO技術棧公眾號

国产又粗又硬又长又爽| 日本男人操女人| 免费激情视频网站| 日韩高清不卡一区| 欧美精品在线免费观看| 无码成人精品区在线观看| 亚洲综合电影| 亚洲欧美视频在线观看视频| 极品日韩久久| 在线观看国产精品入口男同| 国内成人在线| 中文字幕亚洲一区二区三区五十路| 欧美精品色视频| 成人自拍av| 亚洲一区二区精品久久av| 日本高清视频一区二区三区| 性网爆门事件集合av| 玖玖在线精品| 久久久久久久久久婷婷| 精品伦精品一区二区三区视频密桃 | 国产综合色激情| 夜夜爽夜夜爽精品视频| 视频一区二区三| 欧美一级一区二区三区| 久久成人免费网| 57pao精品| 久久99久久久| 真实国产乱子伦精品一区二区三区| 日韩av在线免费| gogo亚洲国模私拍人体| 草民电影神马电影一区二区| 欧美日韩一区二区三区| 久久福利一区二区| 麻豆传媒视频在线| 欧美经典一区二区三区| 蜜桃视频在线观看91| 亚洲乱熟女一区二区| 国产综合久久久久久鬼色| 国产国语videosex另类| 国内精品福利视频| 国产欧美日本| 国色天香2019中文字幕在线观看| 91精品国产高清一区二区三蜜臀| 久久影院一区| 中文字幕亚洲在线| 色噜噜噜噜噜噜| 国产一区二区亚洲| 亚洲欧美日韩精品| 精品成人av一区二区三区| 国产精品午夜av| 精品国产三级a在线观看| 天天久久综合网| 亚洲国产天堂| 91精品国产91久久久久久一区二区 | 99成人在线| 性欧美在线看片a免费观看| 国产精品久久久久久久精| 亚洲天堂免费| 欧美成人精品激情在线观看| 久久99久久99精品免费看小说| 欧美电影《睫毛膏》| 久久激情视频免费观看| 亚洲色图100p| 在线观看免费一区二区| 欧美肥老妇视频| 免费一级特黄特色大片| 日韩一区二区免费看| 亚洲 日韩 国产第一| 中日韩精品视频在线观看| 中文亚洲欧美| 国产成人精品久久亚洲高清不卡| 亚洲乱码国产乱码精品| 美女精品一区二区| 亚洲free性xxxx护士hd| 亚洲免费视频网| 91麻豆国产在线观看| 日韩一区二区三区资源| 一级毛片视频在线| 亚洲最大成人网4388xx| 国产视频九色蝌蚪| 天堂久久午夜av| 51午夜精品国产| 久久国产劲爆∧v内射| 日韩aaa久久蜜桃av| 国产亚洲一区精品| 久久久精品视频免费观看| 国产日韩欧美高清免费| 国产精品久久久久久久久借妻| 一个人看的www日本高清视频| 国产高清一区日本| 免费观看成人在线| 国产在线观看a视频| 性感美女极品91精品| 久久9精品区-无套内射无码| 美女视频一区| 亚洲激情电影中文字幕| 日本黄色网址大全| av亚洲免费| 九九视频直播综合网| 69成人免费视频| 国精产品一区一区三区mba视频 | 蜜桃91麻豆精品一二三区| 久久久精品天堂| 欧美黄色免费网址| 日韩不卡视频在线观看| 日韩精品一区二区三区老鸭窝 | 456国产精品| 日韩国产精品大片| 欧美怡红院视频| 性生活在线视频| 偷拍自拍亚洲色图| 久久中文字幕在线| www.久久久久久久| 国产精品一区在线观看你懂的| 久久99精品国产99久久| av毛片在线播放| 欧亚一区二区三区| 99re久久精品国产| 午夜电影亚洲| 91精品美女在线| 国产专区在线播放| 午夜av区久久| 特黄特黄一级片| 日韩电影一区| 日韩av片电影专区| 免费看av毛片| 亚洲主播在线播放| 最新免费av网址| 精品美女视频| 青草热久免费精品视频 | 超碰在线网站| 日韩一级高清毛片| 欧美特黄一级片| 欧美aaaaaa午夜精品| 欧美日产一区二区三区在线观看| 91超碰免费在线| 亚洲成人在线视频播放| 久草网站在线观看| 激情丁香综合五月| 免费观看黄色大片| 久久女人天堂| 色妞色视频一区二区三区四区| 一级黄色在线视频| 久久女同精品一区二区| 国产中文字幕在线免费观看| 成人香蕉社区| 97精品在线视频| 西西人体44www大胆无码| 午夜亚洲国产au精品一区二区| 18禁一区二区三区| 欧美天堂亚洲电影院在线观看 | 午夜精品在线视频| 天堂成人在线视频| 精品久久久久久久久久| 国产精品815.cc红桃| 久久久精品午夜少妇| 麻豆av福利av久久av| 自拍偷拍欧美视频| 亚洲一区二区久久| 亚洲综合五月天婷婷丁香| 中文字幕日本不卡| 美女被艹视频网站| 欧美日韩精品一本二本三本 | 欧美在线观看视频一区| 国产精品美女www爽爽爽视频| av在线电影院| 制服丝袜亚洲色图| 国产一级理论片| 91蝌蚪porny| 在线免费观看视频黄| 午夜激情久久| 成人精品一二区| 涩涩视频在线| 国产一区二区三区日韩欧美| 一级片视频网站| 一区2区3区在线看| 国产艳俗歌舞表演hd| 蜜桃一区二区三区四区| 国产手机视频在线观看| 好吊妞国产欧美日韩免费观看网站 | 国产日韩一区二区| 国产精品扒开腿做爽爽爽视频软件| 中文字幕精品—区二区| 亚洲成人久久精品| 色婷婷久久99综合精品jk白丝| 自拍偷拍视频亚洲| 国产一区二区三区美女| 日韩a在线播放| 国产精品久久久久久久久久10秀| 国产精品久久波多野结衣| 深夜成人影院| 九九热这里只有精品6| 欧美日本网站| 日韩精品最新网址| 午夜精品久久久久久久蜜桃| 亚洲激情av在线| 成人无码av片在线观看| 成人久久视频在线观看| 国产精品视频黄色| 999亚洲国产精| 青春草在线视频免费观看| 激情视频极品美女日韩| 国产久一一精品| cao在线视频| www.国产一区| 欧美日韩视频精品二区| 日韩三级视频在线观看| 青娱乐在线免费视频| 亚洲第一成年网| 波多野结衣亚洲一区二区| 国产午夜精品福利| 大乳护士喂奶hd| 国产一区二区三区免费| 欧美婷婷精品激情| 国产亚洲在线观看| 国产精品无码电影在线观看| 欧美理论在线播放| 久久影视中文粉嫩av| 亚洲电影一区| 成人福利视频网| 国产精成人品2018| 欧美在线视频一二三| 毛片网站在线看| 欧美超级免费视 在线| 一区二区高清不卡| 国产一区二区免费| 飘雪影院手机免费高清版在线观看| 日韩欧美亚洲国产另类| 91tv国产成人福利| 在线亚洲+欧美+日本专区| 国产毛片aaa| 午夜精品成人在线视频| 日本少妇激情视频| 亚洲伊人色欲综合网| 精品欧美一区二区久久久久| 亚洲人成人一区二区在线观看| 91麻豆精品久久毛片一级| 中文在线资源观看网站视频免费不卡| 精品人妻一区二区三区香蕉| 成人av在线影院| 亚洲乱妇老熟女爽到高潮的片| 国产精品一色哟哟哟| 最好看的中文字幕| 国产美女视频一区| 天美一区二区三区| 精品一区二区免费在线观看| 成人性生交免费看| 激情五月激情综合网| 色呦色呦色精品| 精品影视av免费| 亚洲欧美天堂在线| 国产精品一品视频| 欧美熟妇精品一区二区| 国产ts人妖一区二区| 久草视频福利在线| 久久综合资源网| 91精品久久久久久久久久久久| 中文字幕欧美日本乱码一线二线| 性欧美精品男男| 中文字幕日韩欧美一区二区三区| 国产午夜精品理论片| 一区二区三区在线视频播放| 精品在线视频免费| 欧美日韩国产中字| 亚洲图片欧美日韩| 在线播放欧美女士性生活| 国产男男gay网站| 精品久久久久久久久久久院品网| 无码精品黑人一区二区三区 | 亚洲毛片一区| 亚洲成熟丰满熟妇高潮xxxxx| 日本特黄久久久高潮| 97人人爽人人| 成人av在线电影| 一卡二卡三卡四卡| 国产精品久线在线观看| 乱h高h女3p含苞待放| 五月天视频一区| 一级一片免费看| 制服丝袜亚洲精品中文字幕| 免费观看国产精品| 永久免费精品影视网站| 中文字幕伦理免费在线视频| 午夜精品三级视频福利| 成人黄色图片网站| av成人午夜| 国产欧美日韩在线一区二区| 国产精品12p| 亚洲永久免费| 永久免费黄色片| 97成人超碰视| 农村黄色一级片| 91久久精品一区二区二区| 国产女无套免费视频| 亚洲激情视频网| 麻豆影视在线观看_| 国内精品视频久久| 日韩国产一二三区| 久久婷婷国产综合尤物精品| 亚洲国产老妈| av无码精品一区二区三区| 国产馆精品极品| 秋霞网一区二区三区| 亚洲sss视频在线视频| 亚洲无码久久久久| 日韩二区三区在线| 中文字幕在线播放网址| 国产精品福利无圣光在线一区| av成人资源| 成年人免费观看的视频| 国产精品三上| 女同性αv亚洲女同志| 国产精品美女久久久久久| av中文在线播放| 精品av综合导航| 免费在线视频欧美| 国产精品人成电影在线观看| 色天天色综合| 女人色极品影院| 国产麻豆精品一区二区| 免费一级黄色录像| 色婷婷狠狠综合| 天天摸天天干天天操| 欧美国产第一页| 电影91久久久| 超碰免费在线公开| 美女www一区二区| 干b视频在线观看| 欧美日韩国产精品一区二区不卡中文| 国产夫妻性生活视频| 久久躁日日躁aaaaxxxx| 欧美爱爱视频| 午夜视频久久久| 日韩av一区二区三区| 熟女少妇内射日韩亚洲| 91国产成人在线| 欧美91精品久久久久国产性生爱| 97在线视频一区| 国产香蕉精品| 久久久久久久久久久99| 成人教育av在线| 久久影院一区二区| 亚洲第一中文字幕| 草草视频在线| 久久精品人成| 久久精品二区三区| 日本少妇xxxxx| 欧美日韩一区高清| 黄色网页在线看| 91在线视频导航| 欧美暴力喷水在线| 亚洲午夜久久久久久久久| 亚洲成人1区2区| 欧美香蕉爽爽人人爽| 国产成人精品视频在线| 精品一区不卡| 欧美wwwwwww| 亚洲精品一二三四区| a视频免费在线观看| 欧美—级高清免费播放| 国产精品99久久免费观看| 欧美激情 国产精品| 久久嫩草精品久久久精品| 草莓视频18免费观看| 少妇精69xxtheporn| 日韩激情欧美| 成人在线免费在线观看| 久久精品视频网| 国产一区二区三区在线观看| 欧美高跟鞋交xxxxxhd| 同性恋视频一区| 国产理论在线播放| 亚洲嫩草精品久久| 人妻少妇一区二区三区| 国产999在线| 91精品啪在线观看国产18| 亚洲国产精品狼友在线观看| 欧美性jizz18性欧美| 91在线网址| 国产一区二区三区四区五区在线| 老司机久久99久久精品播放免费| 亚洲精品电影院| 亚洲电影免费观看高清| 欧亚一区二区| 欧美性潮喷xxxxx免费视频看| 久久久久久免费毛片精品| 国产精品久久久久久无人区| 69**夜色精品国产69乱| 91麻豆国产自产在线观看亚洲| 日批免费观看视频| 欧美中文字幕亚洲一区二区va在线| 免费av毛片在线看| 久久综合福利| 国产盗摄精品一区二区三区在线| 亚洲精品男人的天堂| 免费97视频在线精品国自产拍| 久久99国内| 免费不卡的av| 91精品一区二区三区在线观看| 人成在线免费网站|