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

在異步編程中,你真的懂Promise嗎?

開發 前端
在異步編程中,Promise 扮演了舉足輕重的角色,比傳統的解決方案(回調函數和事件)更合理和更強大。本文帶大家深入理解這個熟悉的陌生人—— Promise。

前言

在異步編程中,Promise 扮演了舉足輕重的角色,比傳統的解決方案(回調函數和事件)更合理和更強大。可能有些小伙伴會有這樣的疑問:2020年了,怎么還在談論Promise?事實上,有些朋友對于這個幾乎每天都在打交道的“老朋友”,貌似全懂,但稍加深入就可能疑問百出,本文帶大家深入理解這個熟悉的陌生人—— Promise。

基本用法

1. 語法

  1. new Promise( function(resolve, reject) {...} /* executor */  ) 
  • 構建 Promise 對象時,需要傳入一個 executor 函數,主要業務流程都在 executor 函數中執行。
  • Promise構造函數執行時立即調用executor 函數, resolve 和 reject 兩個函數作為參數傳遞給executor,resolve 和 reject 函數被調用時,分別將promise的狀態改為fulfilled(完成)或rejected(失敗)。一旦狀態改變,就不會再變,任何時候都可以得到這個結果。
  • 在 executor 函數中調用 resolve 函數后,會觸發 promise.then 設置的回調函數;而調用 reject 函數后,會觸發 promise.catch 設置的回調函數。

值得注意的是,Promise 是用來管理異步編程的,它本身不是異步的,new Promise的時候會立即把executor函數執行,只不過我們一般會在executor函數中處理一個異步操作。比如下面代碼中,一開始是會先打印出2。

  1. let p1 = new Promise(()=>
  2.     setTimeout(()=>
  3.       console.log(1) 
  4.     },1000) 
  5.     console.log(2) 
  6.   }) 
  7. console.log(3) // 2 3 1 

Promise 采用了回調函數延遲綁定技術,在執行 resolve 函數的時候,回調函數還沒有綁定,那么只能推遲回調函數的執行。這具體是啥意思呢?我們先來看下面的例子:

  1. let p1 = new Promise((resolve,reject)=>
  2.   console.log(1); 
  3.   resolve('浪里行舟') 
  4.   console.log(2) 
  5. }) 
  6. // then:設置成功或者失敗后處理的方法 
  7. p1.then(result=>
  8.  //p1延遲綁定回調函數 
  9.   console.log('成功 '+result) 
  10. },reason=>
  11.   console.log('失敗 '+reason) 
  12. }) 
  13. console.log(3) 
  14. // 1 
  15. // 2 
  16. // 3 
  17. // 成功 浪里行舟 

new Promise的時候先執行executor函數,打印出 1、2,Promise在執行resolve時,觸發微任務,還是繼續往下執行同步任務, 執行p1.then時,存儲起來兩個函數(此時這兩個函數還沒有執行),然后打印出3,此時同步任務執行完成,最后執行剛剛那個微任務,從而執行.then中成功的方法。

2. 錯誤處理

Promise 對象的錯誤具有“冒泡”性質,會一直向后傳遞,直到被 onReject 函數處理或 catch 語句捕獲為止。具備了這樣“冒泡”的特性后,就不需要在每個 Promise 對象中單獨捕獲異常了。

要遇到一個then,要執行成功或者失敗的方法,但如果此方法并沒有在當前then中被定義,則順延到下一個對應的函數:

  1. function executor (resolve, reject) { 
  2.   let rand = Math.random() 
  3.   console.log(1) 
  4.   console.log(rand) 
  5.   if (rand > 0.5) { 
  6.     resolve() 
  7.   } else { 
  8.     reject() 
  9.   } 
  10. var p0 = new Promise(executor) 
  11. var p1 = p0.then((value) => { 
  12.   console.log('succeed-1') 
  13.   return new Promise(executor) 
  14. }) 
  15. var p2 = p1.then((value) => { 
  16.   console.log('succeed-2') 
  17.   return new Promise(executor) 
  18. }) 
  19. p2.catch((error) => { 
  20.   console.log('error', error) 
  21. }) 
  22. console.log(2) 

這段代碼有三個 Promise 對象:p0~p2。無論哪個對象里面拋出異常,都可以通過最后一個對象 p2.catch 來捕獲異常,通過這種方式可以將所有 Promise 對象的錯誤合并到一個函數來處理,這樣就解決了每個任務都需要單獨處理異常的問題。

通過這種方式,我們就消滅了嵌套調用和頻繁的錯誤處理,這樣使得我們寫出來的代碼更加優雅,更加符合人的線性思維。

3. Promise鏈式調用

我們都知道可以把多個Promise連接到一起來表示一系列異步驟。這種方式可以實現的關鍵在于以下兩個Promise 固有行為特性:

  • 每次你對Promise調用then,它都會創建并返回一個新的Promise,我們可以將其鏈接起來;
  • 不管從then調用的完成回調(第一個參數)返回的值是什么,它都會被自動設置為被鏈接Promise(第一點中的)的完成。

先通過下面的例子,來解釋一下剛剛這段話是什么意思,然后詳細介紹下鏈式調用的執行流程:

  1. let p1=new Promise((resolve,reject)=>
  2.     resolve(100) // 決定了下個then中成功方法會被執行 
  3. }) 
  4. // 連接p1 
  5. let p2=p1.then(result=>
  6.     console.log('成功1 '+result) 
  7.     return Promise.reject(1)  
  8. // 返回一個新的Promise實例,決定了當前實例是失敗的,所以決定下一個then中失敗方法會被執行 
  9. },reason=>
  10.     console.log('失敗1 '+reason) 
  11.     return 200 
  12. }) 
  13. // 連接p2  
  14. let p3=p2.then(result=>
  15.     console.log('成功2 '+result) 
  16. },reason=>
  17.     console.log('失敗2 '+reason) 
  18. }) 
  19. // 成功1 100 
  20. // 失敗2 1 

我們通過返回 Promise.reject(1) ,完成了第一個調用then創建并返回的promise p2。p2的then調用在運行時會從return Promise.reject(1) 語句接受完成值。當然,p2.then又創建了另一個新的promise,可以用變量p3存儲。

new Promise出來的實例,成功或者失敗,取決于executor函數執行的時候,執行的是resolve還是reject決定的,或executor函數執行發生異常錯誤,這兩種情況都會把實例狀態改為失敗的。

p2執行then返回的新實例的狀態,決定下一個then中哪一個方法會被執行,有以下幾種情況:

  • 不論是成功的方法執行,還是失敗的方法執行(then中的兩個方法),凡是執行拋出了異常,則都會把實例的狀態改為失敗。
  • 方法中如果返回一個新的Promise實例(比如上例中的Promise.reject(1)),返回這個實例的結果是成功還是失敗,也決定了當前實例是成功還是失敗。
  • 剩下的情況基本上都是讓實例變為成功的狀態,上一個then中方法返回的結果會傳遞到下一個then的方法中。

我們再來看個例子:

  1. new Promise(resolve=>
  2.     resolve(a) // 報錯  
  3. // 這個executor函數執行發生異常錯誤,決定下個then失敗方法會被執行 
  4. }).then(result=>
  5.     console.log(`成功:${result}`) 
  6.     return result*10 
  7. },reason=>
  8.     console.log(`失敗:${reason}`) 
  9. // 執行這句時候,沒有發生異常或者返回一個失敗的Promise實例,所以下個then成功方法會被執行 
  10. // 這里沒有return,最后會返回 undefined 
  11. }).then(result=>
  12.     console.log(`成功:${result}`) 
  13. },reason=>
  14.     console.log(`失敗:${reason}`) 
  15. }) 
  16. // 失敗:ReferenceError: a is not defined 
  17. // 成功:undefined 

4. async & await

從上面一些例子,我們可以看出,雖然使用 Promise 能很好地解決回調地獄的問題,但是這種方式充滿了 Promise 的 then() 方法,如果處理流程比較復雜的話,那么整段代碼將充斥著 then,語義化不明顯,代碼不能很好地表示執行流程。

ES7中新增的異步編程方法,async/await的實現是基于 Promise的,簡單而言就是async 函數就是返回Promise對象,是generator的語法糖。很多人認為async/await是異步操作的終極解決方案:

  • 語法簡潔,更像是同步代碼,也更符合普通的閱讀習慣;
  • 改進JS中異步操作串行執行的代碼組織方式,減少callback的嵌套;
  • Promise中不能自定義使用try/catch進行錯誤捕獲,但是在Async/await中可以像處理同步代碼處理錯誤。

不過也存在一些缺點,因為 await 將異步代碼改造成了同步代碼,如果多個異步代碼沒有依賴性卻使用了 await 會導致性能上的降低。

  1. async function test() { 
  2.   // 以下代碼沒有依賴性的話,完全可以使用 Promise.all 的方式 
  3.   // 如果有依賴性的話,其實就是解決回調地獄的例子了 
  4.   await fetch(url1) 
  5.   await fetch(url2) 
  6.   await fetch(url3) 

觀察下面這段代碼,你能判斷出打印出來的內容是什么嗎?

  1. let p1 = Promise.resolve(1) 
  2. let p2 = new Promise(resolve => { 
  3.   setTimeout(() => { 
  4.     resolve(2) 
  5.   }, 1000) 
  6. }) 
  7. async function fn() { 
  8.   console.log(1) 
  9. // 當代碼執行到此行(先把此行),構建一個異步的微任務 
  10. // 等待promise返回結果,并且await下面的代碼也都被列到任務隊列中 
  11.   let result1 = await p2 
  12.   console.log(3) 
  13.   let result2 = await p1 
  14.   console.log(4) 
  15. fn() 
  16. console.log(2) 
  17. // 1 2 3 4 

如果 await 右側表達邏輯是個 promise,await會等待這個promise的返回結果,只有返回的狀態是resolved情況,才會把結果返回,如果promise是失敗狀態,則await不會接收其返回結果,await下面的代碼也不會在繼續執行。

  1. let p1 = Promise.reject(100) 
  2. async function fn1() { 
  3.   let result = await p1 
  4.   console.log(1) //這行代碼不會執行 

我們再來看道比較復雜的題目:

  1. console.log(1) 
  2. setTimeout(()=>{console.log(2)},1000) 
  3. async function fn(){ 
  4.     console.log(3) 
  5.     setTimeout(()=>{console.log(4)},20) 
  6.     return Promise.reject() 
  7. async function run(){ 
  8.     console.log(5) 
  9.     await fn() 
  10.     console.log(6) 
  11. run() 
  12. //需要執行150ms左右 
  13. for(let i=0;i<90000000;i++){} 
  14. setTimeout(()=>
  15.     console.log(7) 
  16.     new Promise(resolve=>
  17.         console.log(8) 
  18.         resolve() 
  19.     }).then(()=>{console.log(9)}) 
  20. },0) 
  21. console.log(10) 
  22. // 1 5 3 10 4 7 8 9 2 

做這道題之前,讀者需明白:

  • 基于微任務的技術有 MutationObserver、Promise 以及以 Promise 為基礎開發出來的很多其他的技術,本題中resolve()、await fn()都是微任務。
  • 不管宏任務是否到達時間,以及放置的先后順序,每次主線程執行棧為空的時候,引擎會優先處理微任務隊列,處理完微任務隊列里的所有任務,再去處理宏任務。

接下來,我們一步一步分析:

  • 首先執行同步代碼,輸出 1,遇見第一個setTimeout,將其回調放入任務隊列(宏任務)當中,繼續往下執行
  • 運行run(),打印出 5,并往下執行,遇見 await fn(),將其放入任務隊列(微任務)
  • await fn() 當前這一行代碼執行時,fn函數會立即執行的,打印出3,遇見第二個setTimeout,將其回調放入任務隊列(宏任務),await fn() 下面的代碼需要等待返回Promise成功狀態才會執行,所以6是不會被打印的。
  • 繼續往下執行,遇到for循環同步代碼,需要等150ms,雖然第二個setTimeout已經到達時間,但不會執行,遇見第三個setTimeout,將其回調放入任務隊列(宏任務),然后打印出10。值得注意的是,這個定時器 推遲時間0毫秒實際上達不到的。根據HTML5標準,setTimeOut推遲執行的時間,最少是4毫秒。
  • 同步代碼執行完畢,此時沒有微任務,就去執行宏任務,上面提到已經到點的setTimeout先執行,打印出4
  • 然后執行下一個setTimeout的宏任務,所以先打印出7,new Promise的時候會立即把executor函數執行,打印出8,然后在執行resolve時,觸發微任務,于是打印出9
  • 最后執行第一個setTimeout的宏任務,打印出2

常用的方法

1. Promise.resolve()

Promise.resolve(value)方法返回一個以給定值解析后的Promise 對象。Promise.resolve()等價于下面的寫法:

  1. Promise.resolve('foo') 
  2. // 等價于 
  3. new Promise(resolve => resolve('foo')) 

Promise.resolve方法的參數分成四種情況。

(1)參數是一個 Promise 實例

如果參數是 Promise 實例,那么Promise.resolve將不做任何修改、原封不動地返回這個實例。

  1. const p1 = new Promise(function (resolve, reject) { 
  2.   setTimeout(() => reject(new Error('fail')), 3000) 
  3. }) 
  4. const p2 = new Promise(function (resolve, reject) { 
  5.   setTimeout(() => resolve(p1), 1000) 
  6. }) 
  7. p2 
  8.   .then(result => console.log(result)) 
  9.   .catch(error => console.log(error)) 
  10. // Error: fail 

上面代碼中,p1是一個 Promise,3 秒之后變為rejected。p2的狀態在 1 秒之后改變,resolve方法返回的是p1。由于p2返回的是另一個 Promise,導致p2自己的狀態無效了,由p1的狀態決定p2的狀態。所以,后面的then語句都變成針對后者(p1)。又過了 2 秒,p1變為rejected,導致觸發catch方法指定的回調函數。

(2)參數不是具有then方法的對象,或根本就不是對象

  1. Promise.resolve("Success").then(function(value) { 
  2.  // Promise.resolve方法的參數,會同時傳給回調函數。 
  3.   console.log(value); // "Success" 
  4. }, function(value) { 
  5.   // 不會被調用 
  6. }); 

(3)不帶有任何參數

Promise.resolve()方法允許調用時不帶參數,直接返回一個resolved狀態的 Promise 對象。如果希望得到一個 Promise 對象,比較方便的方法就是直接調用Promise.resolve()方法。

  1. Promise.resolve().then(function () { 
  2.   console.log('two'); 
  3. }); 
  4. console.log('one'); 
  5. // one two 

(4)參數是一個thenable對象

thenable對象指的是具有then方法的對象,Promise.resolve方法會將這個對象轉為 Promise 對象,然后就立即執行thenable對象的then方法。

  1. let thenable = { 
  2.   then: function(resolve, reject) { 
  3.     resolve(42); 
  4.   } 
  5. }; 
  6. let p1 = Promise.resolve(thenable); 
  7. p1.then(function(value) { 
  8.   console.log(value);  // 42 
  9. }); 

2. Promise.reject()

Promise.reject()方法返回一個帶有拒絕原因的Promise對象。

  1. new Promise((resolve,reject) => { 
  2.     reject(new Error("出錯了")); 
  3. }); 
  4. // 等價于 
  5.  Promise.reject(new Error("出錯了"));   
  6.  
  7. // 使用方法 
  8. Promise.reject(new Error("BOOM!")).catch(error => { 
  9.     console.error(error); 
  10. }); 

值得注意的是,調用resolve或reject以后,Promise 的使命就完成了,后繼操作應該放到then方法里面,而不應該直接寫在resolve或reject的后面。所以,最好在它們前面加上return語句,這樣就不會有意外。

  1. new Promise((resolve, reject) => { 
  2.   return reject(1); 
  3.   // 后面的語句不會執行 
  4.   console.log(2); 
  5. }) 

3. Promise.all()

  1. let p1 = Promise.resolve(1) 
  2. let p2 = new Promise(resolve => { 
  3.   setTimeout(() => { 
  4.     resolve(2) 
  5.   }, 1000) 
  6. }) 
  7. let p3 = Promise.resolve(3) 
  8. Promise.all([p3, p2, p1]) 
  9.   .then(result => { 
  10.  // 返回的結果是按照Array中編寫實例的順序來 
  11.     console.log(result) // [ 3, 2, 1 ] 
  12.   }) 
  13.   .catch(reason => { 
  14.     console.log("失敗:reason") 
  15.   }) 

Promise.all 生成并返回一個新的 Promise 對象,所以它可以使用 Promise 實例的所有方法。參數傳遞promise數組中所有的 Promise 對象都變為resolve的時候,該方法才會返回, 新創建的 Promise 則會使用這些 promise 的值。

如果參數中的任何一個promise為reject的話,則整個Promise.all調用會立即終止,并返回一個reject的新的 Promise 對象。

4. Promise.allSettled()

有時候,我們不關心異步操作的結果,只關心這些操作有沒有結束。這時,ES2020 引入Promise.allSettled()方法就很有用。如果沒有這個方法,想要確保所有操作都結束,就很麻煩。Promise.all()方法無法做到這一點。

假如有這樣的場景:一個頁面有三個區域,分別對應三個獨立的接口數據,使用 Promise.all 來并發請求三個接口,如果其中任意一個接口出現異常,狀態是reject,這會導致頁面中該三個區域數據全都無法出來,顯然這種狀況我們是無法接受,Promise.allSettled的出現就可以解決這個痛點:

  1. Promise.allSettled([ 
  2.   Promise.reject({ code: 500, msg: '服務異常' }), 
  3.   Promise.resolve({ code: 200, list: [] }), 
  4.   Promise.resolve({ code: 200, list: [] }) 
  5. ]).then(res => { 
  6.   console.log(res) 
  7.   /* 
  8.     0: {status: "rejected", reason: {…}} 
  9.     1: {status: "fulfilled", value: {…}} 
  10.     2: {status: "fulfilled", value: {…}} 
  11.   */ 
  12.   // 過濾掉 rejected 狀態,盡可能多的保證頁面區域數據渲染 
  13.   RenderContent( 
  14.     res.filter(el => { 
  15.       return el.status !== 'rejected' 
  16.     }) 
  17.   ) 
  18. }) 

Promise.allSettled跟Promise.all類似, 其參數接受一個Promise的數組, 返回一個新的Promise, 唯一的不同在于, 它不會進行短路, 也就是說當Promise全部處理完成后,我們可以拿到每個Promise的狀態, 而不管是否處理成功。

5. Promise.race()

Promise.all()方法的效果是"誰跑的慢,以誰為準執行回調",那么相對的就有另一個方法"誰跑的快,以誰為準執行回調",這就是Promise.race()方法,這個詞本來就是賽跑的意思。race的用法與all一樣,接收一個promise對象數組為參數。

Promise.all在接收到的所有的對象promise都變為FulFilled或者Rejected狀態之后才會繼續進行后面的處理,與之相對的是Promise.race只要有一個promise對象進入FulFilled或者Rejected狀態的話,就會繼續進行后面的處理。

  1. // `delay`毫秒后執行resolve 
  2. function timerPromisefy(delay) { 
  3.     return new Promise(resolve => { 
  4.         setTimeout(() => { 
  5.             resolve(delay); 
  6.         }, delay); 
  7.     }); 
  8. // 任何一個promise變為resolve或reject的話程序就停止運行 
  9. Promise.race([ 
  10.     timerPromisefy(1), 
  11.     timerPromisefy(32), 
  12.     timerPromisefy(64) 
  13. ]).then(function (value) { 
  14.     console.log(value);    // => 1 
  15. }); 

上面的代碼創建了3個promise對象,這些promise對象會分別在1ms、32ms 和 64ms后變為確定狀態,即FulFilled,并且在第一個變為確定狀態的1ms后,.then注冊的回調函數就會被調用。

6. Promise.prototype.finally()

ES9 新增 finally() 方法返回一個Promise。在promise結束時,無論結果是fulfilled或者是rejected,都會執行指定的回調函數。這為在Promise是否成功完成后都需要執行的代碼提供了一種方式。這避免了同樣的語句需要在then()和catch()中各寫一次的情況。

比如我們發送請求之前會出現一個loading,當我們請求發送完成之后,不管請求有沒有出錯,我們都希望關掉這個loading。

  1. this.loading = true 
  2. request() 
  3.   .then((res) => { 
  4.     // do something 
  5.   }) 
  6.   .catch(() => { 
  7.     // log err 
  8.   }) 
  9.   .finally(() => { 
  10.     this.loading = false 
  11.   }) 

finally方法的回調函數不接受任何參數,這表明,finally方法里面的操作,應該是與狀態無關的,不依賴于 Promise 的執行結果。

實際應用

假設有這樣一個需求:紅燈 3s 亮一次,綠燈 1s 亮一次,黃燈 2s 亮一次;如何讓三個燈不斷交替重復亮燈?三個亮燈函數已經存在:

  1. function red() { 
  2.     console.log('red'); 
  3. function green() { 
  4.     console.log('green'); 
  5. function yellow() { 
  6.     console.log('yellow'); 

這道題復雜的地方在于需要“交替重復”亮燈,而不是亮完一遍就結束的一錘子買賣,我們可以通過遞歸來實現:

  1. // 用 promise 實現 
  2. let task = (timer, light) => { 
  3.   return new Promise((resolve, reject) => { 
  4.     setTimeout(() => { 
  5.       if (light === 'red') { 
  6.         red() 
  7.       } 
  8.       if (light === 'green') { 
  9.         green() 
  10.       } 
  11.       if (light === 'yellow') { 
  12.         yellow() 
  13.       } 
  14.       resolve() 
  15.     }, timer); 
  16.   }) 
  17. let step = () => { 
  18.   task(3000, 'red') 
  19.     .then(() => task(1000, 'green')) 
  20.     .then(() => task(2000, 'yellow')) 
  21.     .then(step) 
  22. step() 

同樣也可以通過async/await 的實現:

  1. //  async/await 實現 
  2. let step = async () => { 
  3.   await task(3000, 'red') 
  4.   await task(1000, 'green') 
  5.   await task(2000, 'yellow') 
  6.   step() 
  7. step() 

使用 async/await 可以實現用同步代碼的風格來編寫異步代碼,毫無疑問,還是 async/await 的方案更加直觀,不過深入理解Promise 是掌握async/await的基礎。 

 

責任編輯:趙寧寧 來源: 前端工匠
相關推薦

2019-05-13 14:17:06

抓包Web安全漏洞

2019-10-18 09:50:47

網絡分層模型網絡協議

2019-09-15 10:38:28

網絡分層模型

2023-11-29 08:03:05

2021-08-30 15:41:13

Kafka運維數據

2017-11-07 12:35:53

比特幣區塊鏈虛擬貨幣

2023-10-24 08:53:24

FutureTas并發編程

2021-01-22 07:48:07

JavaScript 高階函數閉包

2024-10-16 17:10:41

2021-04-07 19:44:27

JavaStringHashMap

2018-07-17 16:26:17

大數據營銷消費者

2016-01-07 11:18:50

用戶畫像

2021-06-06 19:51:07

JavaScript異步編程

2023-01-12 11:23:11

Promise異步編程

2024-11-08 09:48:38

異步編程I/O密集

2015-12-23 10:00:04

多種編程語言

2017-05-31 08:45:03

2022-09-22 14:55:31

前端JavaScripthis

2022-09-26 13:10:17

JavaScriptthis

2017-06-27 13:50:37

數據分析Session
點贊
收藏

51CTO技術棧公眾號

亚洲女优在线| 国产精品网站在线看| 最新高清无码专区| 97超碰在线播放| 久久狠狠高潮亚洲精品| 在线成人动漫av| 欧美日韩精品高清| 日本久久久网站| 天天色综合久久| 日韩电影免费在线看| 久久综合网hezyo| 日本三级日本三级日本三级极| 超碰高清在线| 欧美激情一二三区| av一区二区三区免费| 天堂中文在线网| 国产精品久久久久久久久妇女| 日韩精品资源二区在线| 国产日韩一区二区在线观看| 黄视频在线观看网站| eeuss鲁片一区二区三区在线观看 eeuss影院一区二区三区 | av免费看网址| 午夜视频在线免费观看| 粉嫩嫩av羞羞动漫久久久| 热久久99这里有精品| 国产精品国产精品88| 动漫视频在线一区| 欧美日韩成人一区| www国产黄色| 亚洲性图自拍| 中文在线一区二区| 精品在线一区| 国产成人av免费看| 日韩av一区二| 欧洲成人午夜免费大片| 欧美卡一卡二卡三| 国产99亚洲| 精品精品国产高清a毛片牛牛 | free性m.freesex欧美| 国产精品网站在线| 奇米视频888战线精品播放| 蜜臀久久99精品久久久| 国产乱码精品一区二区三区av | 日韩欧美一级片| 亚洲一级片网站| 欧美成人a交片免费看| 亚洲国产日韩精品| 久久亚洲国产成人精品无码区| yiren22亚洲综合伊人22| 成人福利视频网站| 成人蜜桃视频| 性少妇videosexfreexxx片| 理论片日本一区| 国产精品久久久久久久久久尿 | 久久人人爽av| 国产私拍福利精品视频二区| 欧美午夜久久久| 国产av国片精品| 另类视频在线| 亚洲一区二区精品视频| www婷婷av久久久影片| 国产精品扒开做爽爽爽的视频| 久久精品日产第一区二区三区高清版 | av大片免费在线观看| 欧美日韩久久| 欧美激情videoshd| 国产一国产二国产三| 亚洲国产一区二区三区a毛片 | 激情都市亚洲| 色综合久久中文字幕| 国产淫片av片久久久久久| 欧美色网一区| 欧美性生活影院| 一区二区三区 欧美| 韩国精品视频在线观看| 欧美日韩精品一区二区三区四区 | 爱情岛论坛亚洲入口| 精品免费久久久| 高清在线不卡av| 国产亚洲一区二区三区在线播放| 少妇一区二区三区四区| 91麻豆精东视频| 日本一区视频在线观看| 中文字幕日本在线观看| 亚洲日韩欧美一区二区在线| 日本黄网站色大片免费观看| 91福利区在线观看| 欧美午夜精品久久久久久人妖 | 欧美黄色免费看| 黄色在线一区| 人人做人人澡人人爽欧美| 激情网站在线观看| 国产一区欧美一区| 国产亚洲情侣一区二区无 | 日韩在线视频观看正片免费网站| 91麻豆制片厂| 午夜久久一区| 欧美在线视频免费播放| 中文字幕一区二区免费| 国产成人在线影院| 蜜桃久久精品乱码一区二区 | 青青国产在线视频| 国产精品一区二区91| 精品久久久久久一区| 福利成人在线观看| 亚洲综合激情网| 蜜臀久久99精品久久久酒店新书 | 97碰碰视频| 日韩电影免费| 亚洲精品免费在线观看| 久久网站免费视频| 麻豆精品国产| 亚洲视频在线播放| 久久99久久98精品免观看软件| 久久久久国产精品一区二区| 亚洲一区二区三| 久草视频在线看| 亚洲乱码日产精品bd| 99视频在线免费| 北条麻妃在线一区二区免费播放| 永久免费看mv网站入口亚洲| 亚洲精品77777| 久久国产人妖系列| 欧美国产一区二区在线| 呦呦在线视频| 欧美视频完全免费看| 青青草视频网站| 91精品国产乱码久久久久久久 | 亚洲二区中文字幕| 亚洲综合久久av一区二区三区| 一本色道久久| 97人人模人人爽人人喊38tv| 999国产在线视频| 色综合久久九月婷婷色综合| 国内精品免费视频| 希岛爱理一区二区三区| 日本久久久久久久久久久| 亚洲精品一区二区三区新线路| 国产精品久久久久一区二区三区共| 9久久9毛片又大又硬又粗| 日韩成人视屏| 久久久999精品视频| 免费看污视频的网站| 99久久99久久精品国产片果冻| 蜜臀av.com| 涩涩涩久久久成人精品| 在线观看日韩欧美| 国产男人搡女人免费视频| www亚洲一区| 久久99中文字幕| 凹凸av导航大全精品| 欧美福利视频在线观看| 99视频在线观看免费| 中文字幕一区日韩精品欧美| 国产免费又粗又猛又爽| 国产一区二区三区日韩精品 | 日本黄色播放器| 国产亚洲精彩久久| 在线观看久久av| 在线视频免费观看一区| 中文字幕不卡一区| 色乱码一区二区三区在线| 第九色区aⅴ天堂久久香| 国产成人福利视频| yes4444视频在线观看| 欧美亚洲高清一区| 三级黄色片在线观看| 久久精品国产久精国产爱| 天堂社区 天堂综合网 天堂资源最新版 | 欧美国产一级片| 欧美激情一区二区在线| 激情黄色小视频| 欧美激情欧美| 亚洲www永久成人夜色| 青青草原国产在线| 亚洲国产精品电影在线观看| av黄色在线看| 日本一区二区三区在线不卡| 99sesese| 欧美色综合网| 久久福利电影| 欧洲av无码放荡人妇网站| 欧美最新精品| 久久精品国产亚洲精品| 亚洲黄色片视频| 欧美丝袜第一区| 国产视频123区| 国产精品一区二区果冻传媒| 欧美成人三级在线视频| 国产在线日韩精品| 亚洲一区中文字幕在线观看| xxx.xxx欧美| 亚洲毛片一区二区| 在线观看免费观看在线| 亚洲一区视频在线| 亚洲熟妇无码av| 久久精品国内一区二区三区| 国产传媒久久久| aaa级精品久久久国产片| 中文不卡1区2区3区| 日韩在线观看免费| 亚洲国产精品国自产拍久久| 色哟哟日韩精品| 男女羞羞免费视频| 久久久国产午夜精品| 在线视频日韩欧美| 国产日韩1区| 亚洲一区精彩视频| 国产精品欧美大片| 91精品国产综合久久久久久蜜臀 | 日韩少妇裸体做爰视频| 国产精品久久久一本精品| 亚洲色偷偷色噜噜狠狠99网 | 欧美一级免费在线| 久久成人一区| 日本a级片在线播放| 精品日本12videosex| 国产精品美女黄网| 欧美一级做a| 日本精品va在线观看| a级网站在线播放| 亚洲系列中文字幕| 少妇一区二区三区四区| 日韩片之四级片| 最近中文字幕免费在线观看| 午夜一区二区三区视频| 国产精品精品软件男同| 久久精品一区四区| 亚洲av熟女高潮一区二区| 国产自产v一区二区三区c| 免费午夜视频在线观看| 亚洲国产午夜| 日本aa在线观看| 国产精品成人一区二区不卡| 欧美日韩精品中文字幕一区二区| 99这里只有精品视频| 成人深夜直播免费观看| 成人久久网站| 国产精品第3页| 免费h视频在线观看| 久久久久久91| 在线观看中文| 久久综合久久八八| 久草中文在线| 北条麻妃久久精品| 老司机精品影院| 精品国产一区二区三区四区在线观看 | 国产深夜精品福利| 91成人抖音| 国产精品成人免费电影| 国产精品伦理| 日本午夜精品理论片a级appf发布| 成年女人在线看片| 国精产品一区一区三区有限在线| 欧洲中文在线| 欧美国产精品日韩| 人人超在线公开视频| 久久99精品视频一区97| 婷婷av在线| 久久久久久尹人网香蕉| xxx在线免费观看| 97精品视频在线| 亚洲精品**中文毛片| 欧美在线免费看| 欧美一级二级视频| 国产在线999| 人人九九精品视频| 国产不卡一区二区在线观看 | 奇米视频888战线精品播放| 精品黄色一级片| 亚洲日本精品| 亚洲国产精品久久久久蝴蝶传媒| 精品国产无码在线| 欧美视频成人| 日本免费不卡一区二区| 亚洲女同在线| 一区二区三区 日韩| 国产综合久久久久影院| 黄色av电影网站| 91欧美一区二区| www久久久久久久| 亚洲三级电影网站| 男女视频免费看| 色噜噜狠狠色综合欧洲selulu| 亚洲性猛交富婆| 日韩一区二区免费视频| 亚洲人妻一区二区| 伊人亚洲福利一区二区三区| 国产三级在线播放| 91精品国产91| 国语自产精品视频在线看抢先版结局| 91欧美激情另类亚洲| 国产精伦一区二区三区| 日本免费高清一区二区| 午夜久久tv| 爱福利视频一区二区| 激情五月激情综合网| 手机免费看av片| 国产精品视频一区二区三区不卡| 国产av 一区二区三区| 欧美午夜激情视频| 91在线你懂的| 日韩电影在线观看永久视频免费网站| jizzjizz在线观看| 国语自产精品视频在线看一大j8| 免费污视频在线一区| 成人在线视频电影| 欧美一区电影| www插插插无码视频网站| 青青草精品视频| 挪威xxxx性hd极品| 中文字幕一区二区三区在线不卡 | 一区二区三区欧美久久| 欧美一级淫片免费视频黄| 日韩限制级电影在线观看| 欧美日韩在线中文字幕| 欧美日韩电影在线观看| 九色成人搞黄网站| 精品国产综合久久| 欧美日韩亚洲三区| 亚洲免费999| 亚洲国产电影在线观看| 中文字幕日韩一级| 精品国产乱码久久久久久蜜臀| 日本中文字幕视频在线| 国产成人精品日本亚洲| 国产精品宾馆| 日韩欧美视频免费在线观看| 久久国产精品色婷婷| 91激情视频在线观看| 精品国产成人在线| 亚洲av无码国产综合专区 | 成人资源视频网站免费| 欧美国产美女| 午夜欧美福利视频| 久久久噜噜噜久噜久久综合| 国产无码精品久久久| 日韩视频免费直播| 国产三区在线观看| 91情侣偷在线精品国产| 欧美va久久久噜噜噜久久| 丁香婷婷激情网| 久久久久青草大香线综合精品| 日本少妇激情视频| 精品国产乱码久久久久久闺蜜| 日韩欧美一起| 91免费在线观看网站| 欧美va天堂在线| 午夜诱惑痒痒网| 亚洲激情自拍偷拍| 性一交一乱一色一视频麻豆| 欧美黑人又粗大| 91成人午夜| 国产精品一色哟哟| 成人av在线电影| 天堂网一区二区三区| 日韩理论片久久| 不卡一二三区| 免费成人看片网址| 玖玖在线精品| 成人在线观看免费高清| 一区二区三区在线看| 国产喷水福利在线视频| 亚洲色图25p| 香蕉成人影院| 日韩激情视频| 久久国产精品色婷婷| 久草手机视频在线观看| 日韩一二三四区| 中文字幕在线播放网址| 国产精品国色综合久久| 亚洲网站视频| 制服丝袜第二页| 精品露脸国产偷人在视频| 国产精品久久久久久久久毛片| 欧美成人精品在线观看| 免费一区二区三区在线视频| 国产女主播自拍| av资源网一区| 久久久999久久久| 日韩在线视频一区| 一区二区三区四区视频免费观看| 国产精品国产三级国产专区51| 国产精品白丝jk白祙喷水网站| 日本熟女一区二区| 亚洲国产成人精品女人久久久| 玛雅亚洲电影| 日韩欧美在线电影| 国产精品一二一区| 日本一级一片免费视频| 在线观看日韩www视频免费| 999精品视频在线观看| 黄色一级视频在线播放| 91在线精品秘密一区二区| 日韩免费在线视频观看| 夜夜嗨av色综合久久久综合网| 青草综合视频| 欧美老熟妇喷水| 中文字幕高清一区| 日本精品一二区|