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

這次徹底搞懂Promise(手寫源碼多注釋篇)

開發 前端
promise 是 js 里面非常重要的一部分,搞懂了 promise 才能更好的去理解 async,await 和 generator。

[[347964]]

 前言

promise 是 js 里面非常重要的一部分,搞懂了 promise 才能更好的去理解 async,await 和 generator。但是往往很多時候就是不理解 promise 的機制,所以這次通過一步步實現一個 promise 來加深自己的印象,提高自己的思維。

大概的架子

通過我們經常寫的 promise 語法,我們可以先寫一個大概的架子出來,promise 接受回調,并且調用,自身帶有三種狀態,pendding, onFulfilled, onRejected,并且 resolve 這個函數可以讓 pendding 狀態變成 onFulfilled 狀態,同理 reject 函數可以讓 pendding 狀態變成 onRejected 狀態。我們先把上面描述部分實現了。 

  1. const PromiseCopy = function (fn) {  
  2.   this.info = {  
  3.     status: "pending",  
  4.     value: "",  
  5.   };  
  6.   const self = this 
  7.   self.onFulfilledArr = []; // then函數里面的第一個回調函數的集合  
  8.   self.onRejectedArr = []; // then函數里面的第二個回調函數的集合  
  9.   const resolve = function (value) {  
  10.     // 加這個判斷是為了表示,只有在pendding狀態下才會去執行  
  11.     // 狀態已經變成onFulfilled之后就不能再去改變了  
  12.     // 符合PromiseA+中的2.1.2.1  
  13.     if (self.info.status === "pending") {  
  14.       self.info.status = "onFulfilled" 
  15.       self.info.value = value;  
  16.       self.onFulfilledArr.forEach((fn) => fn(value));  
  17.     }  
  18.   };  
  19.   // 和上面同理符合PromiseA+,2.1.3.1  
  20.   const reject = function (value) {  
  21.     if (self.info.status === "pending") {  
  22.       self.info.status = "onRejected"  
  23.       self.info.value = value;  
  24.       self.onRejectedArr.forEach((fn) => fn(value));  
  25.     }  
  26.   };  
  27.   fn(resolve, reject);  
  28. }; 

resolve 的附加實現

其實寫到這里我們的 resolve 函數還是有一些功能沒有實現的, 我們知道 調用 resolve(x), x 的值有好幾種情況,如下

  •  如果 x 是 Promise 實例本身,則拋出錯誤
  •  如果 x 是一個 Promise 對象,那么 then 函數的執行取決這個 x 的狀態,如果 x 也調用 resolve(y),其中 y 也是一個 promise 對象.那么 then 函數的執行取決于這個 promise 對象,依次類推,直到最后一個 promise 狀態更改
  •  如果 x 是一個 thenable 對象,就是一個對象包含 then 這個屬性,或者是一個函數包含一個 then 的靜態方法,那么直接執行 then 函數
  •  如果 x 是一個普通值,直接變成 onFulfilled 狀態,執行后面的 then 函數

思考

  •  網上實現的大部分 resolve 都是我上面的代碼,但是根據規范,resolve 函數里面應該是要判斷上面幾點的,所以我們上面寫的代碼是有誤的
  •  還有一個問題是,我們需要在 resolve 函數里面判斷 x 是不是實例的本身,但是正常的 resolve 函數我們經常是傳入一個參數,所以中間肯定是有一個中間函數的,看下面的代碼 
  1. const PromiseCopy = function (fn) {  
  2.   this.info = {  
  3.     status: "pending", 
  4.      value: "",  
  5.   };  
  6.   const self = this 
  7.   self.onFulfilledArr = []; // then函數里面的第一個回調函數的集合  
  8.   self.onRejectedArr = []; // then函數里面的第二個回調函數的集合  
  9.   // _resolve 是我們經常調用的resolve  
  10.   // 但是真正實現的應該是里面的resolve  
  11.   const _resolve = function (value) {  
  12.     // 這個函數得改變一下  
  13.     // PromiseCopy一旦被實例化,那么self就是實例本身了  
  14.     resolve(self, value);  
  15.   };  
  16.   // 此時我們就可以在resolve進行判斷了  
  17.   const resolve = function (promise, value) {  
  18.     let ifexec = false 
  19.     // 首先判斷value是不是promise本身  
  20.     if (value === promise) {  
  21.       // 一定要用TypeError寫 不然promises-aplus-tests跑不通  
  22.       // 切記這是第一個坑,promises-aplus-tests只認TypeError這種錯誤形式  
  23.       reject(new TypeError("A promise cannot be onFulfilled with itself."));  
  24.     }  
  25.     // value是一個thenable對象  
  26.     // 這個要Object.prototype.toString.call(value) === "[object Object]"判斷 
  27.  
  28.     // 不然resolve([])有問題,不知道是不是我實現問題  
  29.     if (  
  30.       value &&  
  31.       (Object.prototype.toString.call(value) === "[object Object]" ||  
  32.         typeof value === "function")  
  33.     ) {  
  34.       // var promise1 = Promise.resolve(dump).then(function () {  
  35.       //   return {  
  36.       //     then: (resolve, reject) => {  
  37.       //       setTimeout(() => {  
  38.       //         resolve({  
  39.       //           then: (resolve, reject) => {  
  40.       //             resolve("aa111a");  
  41.       //             throw "other";  
  42.       //           },  
  43.       //         });  
  44.       //       });  
  45.       //     },  
  46.       //   };  
  47.       // });  
  48.       // promise1.then(  
  49.       //   (res) => {  
  50.       //     console.log(res === "aa111a");  
  51.       //     console.log("aaa");  
  52.       //   },  
  53.       //   (res) => {  
  54.       //     console.log(res);  
  55.       //     console.log("error");  
  56.       //   }  
  57.       // );  
  58.       // 這里的try--catch一定要加 ,不然會promises-aplus-tests會一直報錯,這是第三個大坑  
  59.       // 因為promises-aplus-test測試里面有這一條的  
  60.       // 看上面注釋例子  
  61.       try {  
  62.         // 拿到then函數  
  63.         const then = value.then;  
  64.         // 如果then是一個函數則執行這個函數  
  65.         if (typeof then === "function") {  
  66.           // 為什么要.call(value, x, y) 你們可以自己試一下原生的Promise在這種情況下this指向的就是value,所以要綁定  
  67.           // 因為then我們已經拿出來了then = value.then,直接調用then(),this就指向的window  
  68.           // 為什么后面還需要綁定兩個函數了  
  69.           // 根據原生的Promise可知,thenable中的then函數可以接受兩個函數resolve,reject  
  70.           // 只有手動調用了resolve和reject才會執行后面的.then操作,具體大家自己操作下  
  71.           then.call(  
  72.             value, 
  73.              function (value) {  
  74.               if (ifexec) {  
  75.                 return;  
  76.               }  
  77.               // ifexec這個一定要加,不然也會報200ms錯誤,第四個大坑  
  78.               // 目的是為了不讓多次執行,語言無法表達看下面的例子  
  79.               // var promise1 = Promise.resolve(dump).then(function () {  
  80.               //   return {  
  81.               //     then: (resolve, reject) => {  
  82.               //       resolve("aa111a");  
  83.               //       resolve("aa111a");  
  84.               //     },  
  85.               //   };  
  86.               // });  
  87.               ifexec = true 
  88.               resolve(promise, value);  
  89.             },  
  90.             function (value) {  
  91.               if (ifexec) {  
  92.                 return;  
  93.               }  
  94.               ifexec = true 
  95.               reject(value);  
  96.             }  
  97.           );  
  98.           return;  
  99.         }  
  100.       } catch (e) {  
  101.         if (ifexec) {  
  102.           return;  
  103.         }  
  104.         ifexec = true 
  105.         reject(e);  
  106.       } 
  107.     }  
  108.     // 下面這一點非常的重要,是async,await 和一些插件比如saga的核心  
  109.     // 就是如果x是一個promise對象,那么then的執行取決于x的狀態  
  110.     // 還有這一個判斷一定要放在這里,不要和上面的換 不然promises-aplus-tests會報一個超過200ms的錯誤,切記這是第二個坑  
  111.     if (value && value instanceof PromiseCopy && value.then === promise.then) {  
  112.       // 將promise的onFulfilledArr給到value  
  113.       // 但是還沒有那么簡單我們要明白兩點  
  114.       // 如果value這個promise已經不是pendding,我們給了他也沒有用,所以需要直接調用  
  115.       if (value.info.status === "pending") {  
  116.         value.onFulfilledArr = self.onFulfilledArr;  
  117.         value.onRejectedArr = self.onRejectedArr;  
  118.       }  
  119.       // 如果value狀態是onFulfilled  
  120.       if (value.info.status === "onRejected") {  
  121.         self.info.value = value.info.value;  
  122.         self.onRejectedArr.forEach((fn) => fn(value.info.value)); 
  123.       }  
  124.       // 如果value狀態是reject  
  125.       if (value.info.status === "onFulfilled") {  
  126.         self.info.value = value.info.value;  
  127.         self.onFulfilledArr.forEach((fn) => fn(value.info.value));  
  128.       }  
  129.       return;  
  130.     }  
  131.     // 如果是一個普通的值  
  132.     // 加這個判斷是為了表示,只有在pendding狀態下才會去執行  
  133.     // 狀態已經變成onFulfilled之后就不能再去改變了  
  134.     // 符合PromiseA+中的2.1.2.1  
  135.     if (self.info.status === "pending") {  
  136.       self.info.status = "onFulfilled" 
  137.       self.info.value = value;  
  138.       self.onFulfilledArr.forEach((fn) => fn(value));  
  139.     }  
  140.   };  
  141.   // 和上面同理符合PromiseA+,2.1.3.1  
  142.   // reject沒有resolve那么多規則,比較簡單  
  143.   const reject = function (value) {  
  144.     if (self.info.status === "pending") {  
  145.       self.info.status = "onRejected" 
  146.       self.info.value = value;  
  147.       self.onRejectedArr.forEach((fn) => fn(value));  
  148.     }  
  149.   };  
  150.   // 此時fn調用的是_reoslve  
  151.   // 這個try catch主要是實現promiseCopy.prototype.catch  
  152.   try {  
  153.     fn(_resolve, reject);  
  154.   } catch (e) {  
  155.     setTimeout(() => {  
  156.       self.onRejectedArr.forEach((fn) => fn(e));  
  157.     });  
  158.   }  
  159. }; 

then 的實現

我們上面介紹的是 promise 的 resolve 用法,promise 還有一個基本用法就是后面接 then,因為是.then 所以我們想到的是這個 then 方法掛在到原型上的,那么 new PromiseCopy 的時候就可以得到這個 then。then 里面是兩個函數,一個是 onFulfilled 后執行的回調,一個是 onRejected 后執行的回調。現在的問題是他是怎么做到 then 里面的函數是在 resolve 和 reject 后執行的?這種推遲執行或者說在某種情況下去執行我們想到的就是觀察者模式了。下面用代碼把上面的話實現一遍,在代碼里面會寫詳細一點的注釋。 

  1. PromiseCopy.prototype.then = function (onFulfilled, onRejected) {  
  2.   const self = this 
  3.   // 這里要判斷下,如果PromiseCopy是resolve了那么就直接執行onFulfilled  
  4.   if (self.info.status === "onFulfilled") {  
  5.     setTimeout(() => {  
  6.       onFulfilled(self.info.value);  
  7.     });  
  8.   }  
  9.   if (self.info.status === "onRejected") {  
  10.     setTimeout(() => {  
  11.       onRejected(self.info.value);  
  12.     }); 
  13.   }  
  14.   // 根據PromiseA+中的2.2.1.1和2.2.1.2,onFulfilled和onRejected必須是函數,不然就會被忽略  
  15.   if (typeof onFulfilled === "function") {  
  16.     self.onFulfilledArr.push(() => {  
  17.       setTimeout(() => {  
  18.         onFulfilled(self.info.value);  
  19.       });  
  20.     });  
  21.   }  
  22.   if (typeof onRejected === "function") {  
  23.     self.onRejectedArr.push(() => {  
  24.       setTimeout(() => {  
  25.         onRejected(self.info.value);  
  26.       });  
  27.     });  
  28.   }  
  29.   // 根據PromiseA+ 2.2.7規范 then函數必須返回一個promise對象  
  30.   return new PromiseCopy((resolve, reject) => {});  
  31. }; 

then 的額外實現

上面實現的 then 也是一個簡單的用法,不過根據 PromiseA+的規范這個 then 函數還有幾個點沒有實現,看代碼解釋 

  1. promise2 = promise1.then(onFulfilled, onRejected);  
  2. promise2.then(onFulfilled, onRejected); 
  •  promise1.then 中的 onFulfilled,onRejected 函數如果返回一個 x,那么當作[[Resolve]](promise2, x)來處理,就跟上面的 resolve 一樣處理,注意如果函數什么都沒有返回,就是返回的 undefined
  •  promise1.then 函數中的兩個回調函數只要有一個報錯,那么直接調用 promise2.then 函數中的錯誤回調
  •  如果 promise1.then 的第一個回調不是函數,并且 promise1 調用的是 resolve,那么 promise2.then 的第一個回調參數是 promise1 中 resolve 函數的拋出值
  •  同理,如果 promise1.then 第二個回調不是函數,并且 promise1 調用的是 reject,那么 promise2.then 中的錯誤回調就會執行

思考

如果像上面這么說的話,這個新拋出來的 promise 何時調用這個 resolve 或者 reject 是一個關鍵, 并且這個拋出的 promise 的執行還得看 onFulfilled 和 onRejected 返回值,這一點當時寫 promise 的時候想了很久,不知道如何組織,后來實在想不出來,看了下網上很多文章,發現這些邏輯都是在 PromiseCopy 主體里面實現的。

return new PromiseCopy((resolve, reject) => {});

then 實現加強版 

  1. PromiseCopy.prototype.then = function (onFulfilled, onRejected) {  
  2.   const self = this 
  3.   // 這個一定要這么寫目的為了讓值傳遞  
  4.   onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (val) => val;  
  5.   // 這個一定要這么寫,一定要拋出一個錯throw err  
  6.   onRejected =  
  7.     typeof onRejected === "function"  
  8.       ? onRejected  
  9.       : (err) => {  
  10.           throw err;  
  11.         };  
  12.   const newnewPromise = new PromiseCopy((resolve, reject) => {  
  13.     if (self.info.status === "onFulfilled") {  
  14.       setTimeout(() => {  
  15.         try {  
  16.           // 如果onFulfilled不是一個函數resolve--self.info.value  
  17.           let value = self.info.value;  
  18.           // 這個注釋不要,留著只是為了記錄當時的思路  
  19.           // 這個加判斷是為了防止then函數逇回調不是一個函數,,是一個字符串  
  20.           //   if (typeof onFulfilled === "function") {  
  21.           //     value = onFulfilled(value);  
  22.           //   }  
  23.           value = onFulfilled(value);  
  24.           // 這里要做一個[[Resolve]](promise2, x)處理了  
  25.           // 因為resolve里面直接做了,所以直接調用,和網上的一些實現有點不一樣  
  26.           // 他們是提取了一個resolvePromise函數調用,我是直接調用了resolve  
  27.           resolve(value);  
  28.         } catch (e) {  
  29.           reject(e);  
  30.         }  
  31.       });  
  32.     }  
  33.     // 注意這里根據上面可知onFulfilled,onRejected拋出的值都要經過[[Resolve]](promise2, x)  
  34.     // 這和resolve,reject不一樣,promise中resolve才走[[Resolve]](promise2, x),reject不走  
  35.     if (self.info.status === "onRejected") {  
  36.       setTimeout(() => {  
  37.         try {  
  38.           let { value } = self.info;  
  39.           value = onRejected(self.info.value); 
  40.           resolve(value);  
  41.         } catch (e) {  
  42.           reject(e);  
  43.         }  
  44.       });  
  45.     }  
  46.     // 如果是pending狀態也需要push  
  47.     if (self.info.status === "pending") {  
  48.       self.onFulfilledArr.push((data) => {  
  49.         setTimeout(() => {  
  50.           try {  
  51.             let value = data 
  52.             value = onFulfilled(value);  
  53.             resolve(value);  
  54.           } catch (e) {  
  55.             reject(e);  
  56.           }  
  57.         });  
  58.       }); 
  59.       self.onRejectedArr.push((data) => {  
  60.         setTimeout(() => {  
  61.           try {  
  62.             let value = data 
  63.             value = onRejected(data);  
  64.             resolve(value);  
  65.           } catch (e) {  
  66.             reject(e); 
  67.            }  
  68.         });  
  69.       });  
  70.     }  
  71.   });  
  72.   return newPromise;  
  73. }; 

小結

到這里 promise 的主體實現已經完成了,下面是測試結果

Promise 其他靜態方法

Promise.resolve 

  1. PromiseCopy.resolve = function (data) {  
  2.   return new PromiseCopy((resolve, reject) => {  
  3.     resolve(data);  
  4.   });  
  5. }; 

reject 

  1. Promise.reject = function (reason) {  
  2.   return new Promise((resolve, reject) => {  
  3.     reject(reason);  
  4.   });  
  5. }; 

Promise.all

這個方法有幾個特點如下

  •  該方法接受一個數組,數組每一個元素都是一個 promise 對象
  •  只有所有 promise 都是 onFulfilled 的時候才會執行 then 回調,并且結果順序和數組的一致
  •  如果其中一個 promise 發生了 reject 那么就會返回這個值 
  1. PromiseCopy.all = function (data) {  
  2.   let count = 0; // 記錄調用次數  
  3.   let total = data.length;  
  4.   let result = []; 
  5.   return new PromiseCopy((resolve, reject) => {  
  6.     for (let i = 0; i < total; i++) {  
  7.       data[i].then(  
  8.         (res) => {  
  9.           result.push(res);  
  10.           ++count;  
  11.           if (count === totla) {  
  12.             resolve(result);  
  13.           }  
  14.         },  
  15.         (res) => {  
  16.           return reject(res);  
  17.         }  
  18.       );  
  19.     }  
  20.   });  
  21. }; 

Promise.race

這個方法也有以下幾個特點

  •  這個方法也是接受數組,數組的元素是 promise
  •  他只返回最快的那一個 promise 的值
  •  就算有錯誤也會返回最快那一個 promise 的值 
  1. PromiseCopy.race = function (data) {  
  2.   const total = data.length;  
  3.   return new PromiseCopy((resolve, reject) => {  
  4.     for (let i = 0; i < total; i++) {  
  5.       data[i].then(  
  6.         (res) => {  
  7.           resolve(res);  
  8.         },  
  9.         (res) => {  
  10.           return reject(res);  
  11.         }  
  12.       );  
  13.     }  
  14.   });  
  15. }; 

catch 方法 

  1. PromiseCopy.prototype.catch = function (onRejected) {  
  2.   // 能到catch里面來的一定是走的reject的  
  3.   // 而且狀態一定是pendding  
  4.   const self = this 
  5.   const newnewPromise = new PromiseCopy((resolve, reject) => {  
  6.     if (self.info.status === "onRejected") {  
  7.       try {  
  8.         setTimeout(() => {  
  9.           let { value } = self.info;  
  10.           if (typeof onRejected === "function") {  
  11.             value = onRejected(self.info.value);  
  12.           }  
  13.           resolve(value);  
  14.         });  
  15.       } catch (e) {  
  16.         rejetc(e);  
  17.       } 
  18.     }  
  19.     if (self.info.status === "pending") {  
  20.       self.onRejectedArr.push((data) => {  
  21.         setTimeout(() => {  
  22.           try {  
  23.             let value = data 
  24.             if (typeof onRejected === "function") {  
  25.               value = onRejected(data);  
  26.             }  
  27.             resolve(value);  
  28.           } catch (e) {  
  29.             reject(e);  
  30.           }  
  31.         });  
  32.       });  
  33.     }  
  34.   });  
  35.   return newPromise;  
  36. };  
  37. // 后來發現catch有一個簡單的實現方法  
  38. // 沒有刪除上面就是為了記錄思路過程  
  39. Promise.prototype.catch = function (onRejected) {  
  40.   return this.then(null, onRejected);  
  41. }; 

deferred

這個是 Promise 提供的一個快捷使用,自己實現 promise 的時候一定要加,不然 promises-aplus-tests promise.js 跑不過 

  1. PromiseCopyPromiseCopy.defer = PromiseCopy.deferred = function () {  
  2.   let dfd = {};  
  3.   dfd.promise = new PromiseCopy((resolve, reject) => {  
  4.     dfd.resolve = resolve;  
  5.     dfd.reject = reject;  
  6.   });  
  7.   return dfd;  
  8. }; 

源碼

promise 源碼已經上傳到個人 github ( https://github.com/yizhengfeng-jj/promise 歡迎 star) 

 

責任編輯:龐桂玉 來源: 前端大全
相關推薦

2025-03-17 00:21:00

2022-02-11 13:44:56

fiber架構React

2021-04-07 20:01:23

Go變量常量

2025-04-21 04:00:00

2020-04-28 22:12:30

Nginx正向代理反向代理

2022-11-11 08:19:03

redis分布式

2022-04-25 09:03:16

JavaScript代碼

2017-07-20 16:55:56

Android事件響應View源碼分析

2022-03-26 08:49:13

MySQL數據存儲

2024-01-03 13:39:00

JS,Javascrip算法

2023-10-18 10:55:55

HashMap

2025-04-11 05:55:00

2025-01-13 16:00:00

服務網關分布式系統架構

2025-06-30 00:32:43

策略模式算法MyBatis

2017-12-05 17:44:31

機器學習CNN卷積層

2020-10-14 08:50:38

搞懂 Netty 線程

2025-05-06 01:14:00

系統編程響應式

2019-06-24 05:05:40

緩沖池查詢數據InnoDB

2024-06-21 08:32:24

2019-06-26 09:41:44

分布式事務微服務
點贊
收藏

51CTO技術棧公眾號

亚洲精品视频在线看| 久久黄色级2电影| 日韩成人久久久| 大陆极品少妇内射aaaaa| 国产玉足榨精视频在线观看| 美女视频一区在线观看| 超碰91人人草人人干| 91视频在线免费| av在线日韩| 亚洲欧美视频一区| 久久精品99久久| 亚洲一卡二卡在线| av成人天堂| 久久视频免费在线播放| 国产精品一级黄片| 精品国产一区二| 日韩欧美在线视频观看| 国产成人在线亚洲欧美| 亚洲一区二区在线看| 91片黄在线观看喷潮| 国产日韩亚洲| 久久在线观看视频| 亚洲久久久久久久| 亚洲精品成av人片天堂无码 | av女优在线播放| 三级在线视频| 国产成人精品aa毛片| 日本午夜人人精品| 午夜少妇久久久久久久久| 亚洲精品国产动漫| 欧美成人在线直播| 欧美日韩一区二区三区69堂| 亚洲黄色免费看| 亚洲国产综合91精品麻豆| 亚洲砖区区免费| 欧美日韩免费做爰大片| a在线欧美一区| av成人综合网| 国产91视频在线| 另类调教123区| 国产精品扒开腿爽爽爽视频| 可以免费看的av毛片| 黄色国产精品| 久久国产精品电影| 欧美h片在线观看| 欧美色蜜桃97| 国产亚洲精品91在线| 色婷婷av777| 欧美自拍一区| 亚洲精品wwww| 久久久久麻豆v国产精华液好用吗| 日韩一区免费| 日韩免费看网站| 伦伦影院午夜理论片| 国产精品美女久久久久| 欧美日本国产一区| 四季av一区二区三区| 性欧美freehd18| 在线一区二区观看| 亚洲男人天堂色| 日韩色淫视频| 欧美性做爰猛烈叫床潮| 网站一区二区三区| 色狠狠一区二区三区| 在线观看91精品国产麻豆| 一区二区在线免费看| 国产欧美日韩电影| 日韩免费电影一区| 日韩aaaaa| 美女搡bbb又爽又猛又黄www| 精品亚洲美女网站| 欧美亚洲一区三区| 777视频在线| 91精品在线免费视频| 8x福利精品第一导航| 亚洲精品中文字幕乱码无线| 五月亚洲婷婷| 亚洲精品成人久久电影| 精品人妻互换一区二区三区| 成人3d精品动漫精品一二三| 久久精品久久久久电影| 精品无码人妻一区二区三区品| 99精品热视频只有精品10| 日韩免费黄色av| 91国内精品久久久| 成人深夜在线观看| 日本在线播放不卡| 大片免费在线看视频| 午夜精品久久久久| 国产视频手机在线播放| 亚洲精品一二三**| 亚洲欧美国产精品久久久久久久| www中文在线| 精品福利电影| 国产精品丝袜久久久久久高清 | 欧美一级欧美一级在线播放| 日本性生活一级片| 精品理论电影在线| 欧美国产日韩一区二区在线观看| 色av性av丰满av| 国产一区二区精品久久91| 黄色91av| av免费看在线| 色偷偷成人一区二区三区91| 国产精品久久久久久9999| 欧美福利在线播放网址导航| 少妇高潮久久77777| 久久露脸国语精品国产91| 蜜臀精品一区二区三区在线观看 | 手机在线播放av| 亚洲午夜久久| 欧美肥婆姓交大片| 国产精品露脸视频| 波波电影院一区二区三区| 国产情人综合久久777777| 国产精品毛片va一区二区三区| 国产高清视频免费最新在线| 亚洲一二三四区不卡| 国产主播中文字幕| 同性恋视频一区| 欧美日本亚洲视频| 在线中文字幕网站| 久久蜜桃av一区二区天堂| 免费看日本黄色| 欧美午夜三级| 亚洲欧美色婷婷| 欧美一级视频免费观看| 国产精品一区二区三区网站| 色一情一乱一伦一区二区三区丨 | 日本福利一区二区| 精品国产乱码久久久久夜深人妻| 久久久久国产| 国产精品久久久久久久电影| 天堂成人在线| 蜜桃视频一区二区| 国产一区二区自拍| 欧美四级在线| 欧美成va人片在线观看| 色老板免费视频| 麻豆精品在线播放| 日韩一区国产在线观看| 美女18一级毛片一品久道久久综合| 欧美不卡123| 欧产日产国产v| 国产一区二区在线观看免费| 夜夜春亚洲嫩草影视日日摸夜夜添夜| 三上悠亚一区二区| 亚洲美女在线视频| 国产综合精品视频| 99re视频精品| 91国视频在线| 色天下一区二区三区| 97av在线视频| 欧美成熟毛茸茸| 日韩欧美国产激情| 在线观看国产精品一区| 日韩电影网1区2区| 亚洲 国产 欧美一区| 69堂免费精品视频在线播放| 色偷偷9999www| 97久久人国产精品婷婷| 亚洲视频一区二区免费在线观看| 成人黄动漫网站免费| 无码精品一区二区三区在线播放 | 国产xxxx振车| av毛片精品| 性欧美暴力猛交69hd| 凸凹人妻人人澡人人添| 欧美日韩免费观看中文| 成年人网站免费看| 日韩av不卡在线观看| 伊人色综合久久天天五月婷| 成人网av.com/| 欧美国产精品va在线观看| 色呦呦视频在线| 一本一道综合狠狠老| 99精品欧美一区二区| 久久99精品久久久久久国产越南 | 免费亚洲电影| 综合av色偷偷网| 精品国产乱码久久久久久蜜臀网站| 亚洲永久免费av| 亚洲av无码一区二区三区观看| 三级成人在线视频| 日本不卡一区二区三区四区| 电影一区二区在线观看| 国产成人精品视频在线| h片在线免费| 亚洲精品久久久久久下一站 | 精品免费国产一区二区三区四区| 久久久久久久久久免费视频| 国产欧美一区二区精品婷婷| 无套白嫩进入乌克兰美女| 香蕉成人久久| 免费国产成人看片在线| 台湾色综合娱乐中文网| 成人黄色生活片| 樱花草涩涩www在线播放| 日日噜噜噜夜夜爽亚洲精品| 色呦呦免费观看| 欧美精品丝袜久久久中文字幕| 日本熟女一区二区| 中文字幕一区二区三区不卡在线 | 鲁大师精品99久久久| 国产精品对白刺激| av在线网页| 日韩在线一区二区三区免费视频| 男人天堂网在线视频| 欧美日韩黄色一区二区| 国产精品500部| 日本午夜免费一区二区| 欧美日韩国产乱码电影| 制服.丝袜.亚洲.中文.综合懂色| 中文字幕一区二区视频| 91中文字幕永久在线| 成人小视频在线| 亚洲va在线va天堂va偷拍| 亚洲综合国产| 无码人妻少妇伦在线电影| 91久久国产| 日韩一本精品| 亚洲视频分类| 精品亚洲欧美日韩| 伊人久久噜噜噜躁狠狠躁| 91日本在线观看| 欧美日韩五区| 日本高清+成人网在线观看| www在线看| 欧美大成色www永久网站婷| av电影在线观看网址| 亚洲男人的天堂在线播放| 欧美视频久久久| 日韩精品专区在线影院重磅| 亚洲一区精品在线观看| 一本大道久久a久久综合| 日本黄色片视频| 亚洲专区一二三| 五月天丁香激情| 亚洲激情自拍视频| 国产高潮国产高潮久久久91| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 国产精品色视频| 欧美男女交配| 国产91免费看片| 电影天堂国产精品| 国产成人综合av| 97精品国产99久久久久久免费| 国产成人黄色av| 成人日韩在线| 国产精品日韩在线观看| 久久91视频| 91精品国产综合久久香蕉最新版| 电影在线观看一区二区| 国产精品99久久久久久白浆小说| 成人免费网站www网站高清| 国产精品久久久| 成人国产精品一区二区免费麻豆| 国产精品一二区| 精品福利在线| 亚洲va男人天堂| 91精品国产自产精品男人的天堂| 国产91亚洲精品一区二区三区| 99精品国产高清一区二区麻豆| 99在线视频首页| 日本中文字幕第一页| 91丨porny丨在线| 国产精品密蕾丝袜| 国产精品久久久爽爽爽麻豆色哟哟| 国产人与禽zoz0性伦| 亚洲欧美一区二区久久| 国产奶水涨喷在线播放| 一本高清dvd不卡在线观看| 欧美激情一区二区三区免费观看| 欧美精品 日韩| wwwav网站| 日韩毛片在线看| 888av在线| 久久久久国产视频| 久久精品女人天堂av免费观看 | 久操网在线观看| 午夜亚洲福利在线老司机| 男女无套免费视频网站动漫| 久99久精品视频免费观看| 性感美女一区二区三区| 久久亚洲免费视频| 波多野结衣家庭教师在线观看| 亚洲色图另类专区| 久久久国产精品成人免费| 欧美日韩另类一区| 日日夜夜精品免费| 中文字幕不卡av| 黄色影院在线看| 国产精品视频公开费视频| 中文字幕一区二区三区四区久久 | 一本到三区不卡视频| 国产精品污视频| 日韩av在线网站| 黄网页在线观看| 欧美一区第一页| 久久久久久亚洲精品美女| 麻豆传媒一区二区| 欧美在线影院| 蜜臀视频一区二区三区| 不卡的av在线播放| 国产suv精品一区二区68| 欧美午夜片欧美片在线观看| av手机免费看| 一本一本久久a久久精品牛牛影视| 一级黄色大片免费观看| 精品国产凹凸成av人网站| 在线激情小视频| 午夜精品久久久久久久久久久久| 久久久久伊人| 欧美美乳视频网站在线观看| 欧美三级午夜理伦三级中文幕| 色戒在线免费观看| 久久网站最新地址| 亚洲精品在线观看av| 91精品国产欧美日韩| 番号在线播放| 欧美性受xxxx白人性爽| 在线视频亚洲欧美中文| 男女激烈动态图| 日本中文字幕不卡| 无码熟妇人妻av| 午夜欧美2019年伦理| 国产精品久久久久久久久免费看| 国内毛片久久| 免费的一级黄色片| 国产一区二区福利| 欧美视频一区二区在线| 欧美日韩精品免费观看视频| 国产午夜视频在线观看| 欧美亚洲一级片| 欧洲亚洲一区二区三区| 男女视频网站在线观看| 国产成人精品一区二区三区四区| 国产免费久久久久| 欧美美女视频在线观看| 免费av在线| 成人免费视频网址| 911久久香蕉国产线看观看| 特黄视频免费观看| 国产精品久久久久婷婷二区次| 中文字幕免费高清在线观看| 国产一级揄自揄精品视频| 你懂得影院夜精品a| 日韩hmxxxx| 老司机一区二区三区| 久久亚洲AV无码专区成人国产| 在线观看www91| av大片在线观看| 国产在线拍揄自揄视频不卡99| 水蜜桃久久夜色精品一区| 中文字幕国内自拍| 亚洲欧洲日韩一区二区三区| 97人妻精品一区二区三区动漫 | 欧美人动性xxxxz0oz| 俄罗斯精品一区二区三区| 激情综合中文娱乐网| 免费a v网站| 色综合激情五月| av资源在线观看免费高清| 国产欧美精品一区二区| 中文字幕人成人乱码| 日韩少妇一区二区| 欧美日韩国产在线看| 国产精品免费观看| 成人黄色在线观看| 尤物网精品视频| 免费在线观看污| 欧美夫妻性生活| 国内在线视频| 欧美日韩在线一区二区三区| 青青草国产成人av片免费| 肉色超薄丝袜脚交69xx图片| 精品国产一区二区精华| 亚洲精品一区| 一区二区在线观看网站| 粉嫩av一区二区三区粉嫩| 免费看毛片网站| 久久久精品国产亚洲| 国内精品国产成人国产三级粉色| 成人免费毛片播放| 亚洲摸摸操操av| 青青操在线视频| 成人日韩在线电影| 国产免费www| 久久中国妇女中文字幕| 开心激情综合| 黄色在线视频网| 亚洲国产裸拍裸体视频在线观看乱了| 欧美xxx.com| 亚洲一区二区三区sesese| 先锋亚洲精品| avove在线播放| 亚洲网站在线观看| 中文字幕一区二区三区四区久久 | 国产亚洲xxx| av不卡一区|