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

多圖剖析公式 Async=Promise+Generator+自動執行器

開發 前端
Javascript 異步編程先后經歷了四個階段,分別是Callback 階段,Promise 階段,Generator 階段和 Async/Await 階段。

大家好,我是二哥。

??上篇??既是 Node.js 的核心,也是理解今天這篇的基礎。對 event-loop ,Node.js 官網有下面這樣一段描述。希望上一篇能幫你更好地理解這句話。

The event loop is what allows Node.js to perform non-blocking I/O operations  despite the fact that JavaScript is single-threaded  by offloading operations to the system kernel whenever possible.

這篇我們來剖析 async 的實現機制。文章有點長,還略為燒腦。如果沒有耐心一次看完,建議分批次看。

異步編程的好處多多,主線程負責策略,工作線程負責機制,完美匹配 Unix 的設計哲學:策略和機制分離。發號施令的是策略,苦逼干活的是機制。

Javascript 異步編程先后經歷了四個階段,分別是 callback 階段,Promise 階段,Generator 階段和 Async/Await 階段。

callback 很快就被發現存在回調地獄和控制權問題,Promise 就是在這個時間出現的,用來解決這些地獄問題。Promise 用起來的感覺當然是比 callback 絲滑太多,但碼農們使用一段時間后發現它的使用體驗還是比不上同步代碼。

我們知道同步代碼有一個無論 callback 還是 Promise 都無法比擬的優點:代碼是一行一行運行的。如果哪行代碼被阻塞了,CPU就暫停運行,直到阻塞解除后再繼續。也就說請求發生的地方和請求完成的位置是挨在一起的,雖然時間上有先后,但空間上卻是連續的。

那有沒有一種語法,能讓我們既享受到異步編程的好處,又能有同步編程那樣的體驗呢?當然有!它就是 async/await 。其實大家一直在用 async/await ,也早就感受到它的優美了:兼具運行效率與結構扁平。

async function asynFn(){
// code block 1
let a1 = await ( Promise instance a ) // LINE-A
// code block 2 // LINE-B
return xxx
}
syncFn()

不過,對于上面這段簡單的代碼,有幾個問題不知道你想過沒?

  • LINE-A 處的 await 語句表示需要等待后面的表達式的結果。“等待”這兩個字意味著變量 a1 的求值和 LINE-B 處代碼的執行時機被延后了。這個延后操作是怎么做到的呢?用 new Promise() 創建 Promise instance a 時我們需要給它設置一個函數。在這個函數里,當我們調用 resolved(data) 后,a 的狀態就會變為 fulfilled ,為什么變量 a1 的值就會變成我們調用 resolved(data) 時所設的實參 data 呢?
  • async 和圖 1 所示的單進程多線程模型之間是什么關系?
  • async 是怎么實現的?
async/await = Promise + Generator + 自動執行器

這是二哥總結的公式。它揭示了 async/await  和 Promise / Generator 之間的關系。上車吧,帶著上面的幾個問題和這個公式。

1、event-loop

在開啟我們的旅程之前呢,還是要先來復習上一篇聊到的至關重要的概念:event-loop 。它是 Node.js 的核心。

Node.js 主線程和線程池的配合關系如下圖所示。主線程負責執行 JS  code ,線程池里面的 work thread 負責執行類似訪問 DB、訪問文件這樣的耗時費力的工作,它倆通過消息隊列協調工作。

這和餐館工作流程類似。餐館由一個長得漂亮的小姐姐招呼客人落座并負責收集來自各個餐桌的點單。每次收到一個點好的菜單,小姐姐會迅速地把它通過一個小窗口遞交給后廚。后廚那里有一個小看板,所有的點單都被陳列在看板上。廚師長根據單子的時間和內容安排不同的廚師燒菜。菜燒好后,再由小姐姐負責上菜。

圖片

圖 1:Node.js 主線程和工作線程關系圖

2、Promise

Promise 是什么?我想不需要二哥在這里做過多介紹了。下面是 Promise 的典型使用方法介紹:

const promise = new Promise(/*executor*/ function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
// 對變量 promise 的使用場景 1
promise.then(value => {
// success
})
.catch(error => {
console.log(error);
});
// 對變量 promise 的使用場景 2
promise.then();
// 對變量 promise 的使用場景 3
await promise;

對這段代碼,二哥想在這里說幾個重點:

  1. Promise 是一個 Class,所以需要用 new Promise() 來創建一個 Promise 對象。
  2. Promise 還是一個狀態機。它有三種狀態  pending,fulfilled(resolved) 和 rejected。狀態轉換只能是 pending 到 resolved 或者 pending 到 rejected,且狀態一旦轉換完成,不能再次轉換。
  3. 我們調用 Promise 的then() 方法時所提供的 onResolved / onRejected 函數均是 callback。只有當 Promise 的狀態改變后,它們才會被調用。再強調一遍:只有當狀態改變后,我們通過 then() 方法所設置的 callback 才會被調用。不過也有可能調用 then(onResolved, onRejected) 時,這倆 callback 之一會被立刻執行:當執行 then() 方法的時候,Promise的狀態已經轉換完成了。什么時候會發生這種情況呢?其實很簡單,創建 Promise 對象的時候,我們需要提供一個 callback ,如上面的代碼所示,這里我們稱這個 callback 為 executor。這個 executor 是會被立即執行的,等它執行完了,new Promise() 才會返回,這時我們才可以基于這個 Promise 對象進行鏈式調用。我們只要在 executor 里面調用 resolve / reject 就可以迫使 then() 立即執行 onResolved, onRejected 了。

我們反過來過一遍下面的自問自答:

  • 問:onResolved / onRejected 函數什么時候會被執行?答:當 Promise 的狀態改變的時候。
  • 問:Promise 的狀態什么時候改變?答:當我們在 executor 里面調用 resolved(value) 的時候。
  • 問:那我們什么時候需要調用 resolved(value) ?答:當我們的異步請求做完了的時候。
  • 問:異步請求由誰來負責完成?答:Worker thread 來負責完成異步請求,當 worker thread 的異步操作結束后,通過 event-queue 通知 Node.js 主線程,并在 event-loop 的下一個 tick 擇機執行 callback 函數。

所以這個過程其實是發起異步請求和請求完成后的 callback 函數調用過程。這個過程完全遵循圖1 所示的流程。

3、Generator

Generator 函數是 ES6 提供的一種異步編程解決方案,語法行為與傳統函數完全不同。

圖片

圖 2:Generator 函數示例

let g = gen();
g.next(); // return { value: 300, done: false }
g.next(); // return { value: 400, done: false }
g.next(); // return { value: xxx, done: true }

圖 2 即為一個 Generator 函數。Generator 語法層面的東西不是這篇文章的重點。二哥把它與普通函數最明顯的區別寫在這里:

  • ?像 gen()? 這樣的函數調用,Generator 函數里的代碼不會被立即執行,也即該函數 ① 位置的代碼不會被執行。函數調用會立即返回一個迭代器。既然是迭代器,那么我們可以不斷地通過 g.next()? 來遍歷這個 Generator 內部的狀態。每次  g.next() 調用會返回 { value: xxx, done: xxx} 這樣的 object 。
  • Generator 函數還可以包含一個關鍵字 yield ,如 ② 和 ④ 處代碼所示。yield 會使得函數的執行暫停。
  • ⑥ 處的語句雖然看起來是 return xxx? ,不過實際上該函數返回的卻是 { value: xxx, done: true } 這樣的結構。?

我們可以把 Generator 理解為一個狀態機。它的狀態會隨著 Generator 函數內部代碼的不斷執行而改變。而我們可以通過 g.next() 來遍歷這些狀態。

(1)區分兩個重要的概念

有兩個重要的概念需要區分開來,這對理解 Generator 的精華非常重要:

  • yield 表達式
  • yield 語句

它們之間的關系如圖 3 所示。我還在圖中標出了 Generator 函數執行暫停點,閱讀后文的時候如果被繞暈了,可以回到這里來看看。

圖片

圖 3:yield 表達式和 yield 語句對比

function * gen(){
let a = 1
let b = 2
let a1 = yield a+b // LINE-A
// ^ 第一次調用 next() 暫停的位置
a = a1 ?? 3
b = 4
let a2 = yield a*b // LINE-B
// ^ 再次調用 next() 暫停的位置
return a2 // LINE-C
}
// 以下為 Generator 函數調用者 caller
let g = gen()
let res = g.next() // 第一次調用 next() // LINE-D
// do something accroding to res.value // LINE-E
g.next() // 第二次調用 next()
g.next(); // return { value: xxx, done: true } // LINE-F

像這個代碼里面,LINE-A 處的 a+b 表達式稱為 yield 表達式,表達式的求值結果體現在每次  g.next() 所返回的 Object 的 value 屬性上,也即 {value : 3, done: false} 。而 yield a+b 稱為 yield 語句。那它的返回值是什么呢?默認情況下它返回 undefined,所以 LINE-A 這行代碼執行完后, a1 的值為 undefined。注意我說的是:LINE-A 處的這個 yield 語句執行完后,a1 的值才為 undefined 。

yield 表達式影響到的是 next() 方法調用的返回值,進而改變了調用者的行為,如 LINE-E 處的代碼執行會被 res.value 影響。而 yield 語句影響到的是 LINE-A 處的變量 a1 ,進而改變了 Generator 函數本身的代碼行為,比如 a = a1 ?? 3 變量 a 的取值就會被影響到。實際上 LINE-A 的執行被分成了兩個階段:

  • 第一次調用 next() 從函數起始處開始執行,直到遇到 yield 停下來,我在代碼里標明了暫停點。將表達式 a+b? 求值后,第一次 next() 調用返回 {value : 3, done: false} 。
  • 第二次調用 next() 會從 LINE-A 暫停處繼續執行,直到遇到 LINE-B 處的 yield 停下。將表達式 a*b? 求值后,第二次 next() 調用返回 {value : 12, done: false}。這中間 a1 被賦值一次。當然,它的值為 undefined。?

老讓 a1 為 undefined 多沒意思,我們可以通過在調用 next() 時傳進去一個參數來改變 yield a+b 這條 yield 語句的返回值,注意我說的是改變 yield 語句的返回值,不是 yield 表達式。就像 g.next(100) 這樣,這樣的話,在第二次調用過程中, a1 就變成 100 了。你猜,第二次調用 .next() 得到的 value 是多少?對,這次它是 400(100*4)。

不過這里有個限制,我們不能在第一次執行  g.next() 的時候給它注入一個值。

示例中的 LINE-C 使得 Generator 函數執行終止,故對它的遍歷也就終結了。接著剛才的例子,LINE-F 處最后一次 next() 調用得到的返回值是:{value : 400, done: true} 。

(2)執行權禪讓

如果你還沒有暈的話,我們繼續。如果你暈了的話,返回上一步繼續讀。

你發現了,上面的代碼里,CPU 在執行 Generator 函數的時候,暫停了兩次,且都是遇到 yield 這個關鍵詞的時候暫停的。

每次暫停的點都是在 yield 表達式求值結束之后,但 yield 語句返回之前。請結合二哥在示例中標注的位置,把這句話多讀幾次。

Generator 函數的執行暫停意味著 next() 調用立即返回了,直到下一次 next() 調用,Generator 函數才又得到了可以繼續執行的機會。

你有沒有發現一個有意思的事情?

  • 每次遇到 yield 暫停,意味著 Generator 函數把代碼的執行權交出來了,通過 next() 返回這樣的契機,執行權來到了 caller 手上。
  • caller 再次調用 next() 意味著 Generator 函數又得以恢復運行,也就是說 caller 又以 next() 調用這樣的契機把執行權遞交回 Generator 函數。

二哥給這個過程取了一個好聽的名字:執行權禪讓。

(3)用手動執行器驅動 Generator

到目前為止,我們大概了解了 Generator 相比普通函數的鮮明特征:

  • 對它的調用會立即返回,返回給調用者的是一個迭代器。
  • Generator 函數自己不能自動運行,得通過 next() 啟動執行,每次暫停后,還得再通過 next() 驅動它繼續往前走。
  • 每一次調用迭代器的 next() 會使得 Generator 獲得代碼執行權,并被驅使繼續往前運行,直到遇到下一個 yield 關鍵詞或者 return 語句。
  • 遇到 yield 關鍵詞就意味著本次 next() 調用該返回了,也意味著 Generator 函數該交出代碼執行權了。伴隨著 next() 返回的是 { value: xxx, done: xxx} 這樣的 object 。其中 value 部分是對 yield 表達式求值得到。
  • 我們還可以通過給 next() 傳遞參數從而控制 yield 語句的返回值。

我們把前文所提到的調用者寫得完整一些,如下圖手動執行器旁邊的代碼塊所示,代碼的每一行我用紫色數字標記出來了。再把圖 1的示例代碼稍作修改,把 yield 表達式改為一個 Promise 對象,同樣地,代碼每一行我用黃色數字做了標記。后文我用紫 ① 表示左側代碼第一行,類似地用黃 ① 表示右側代碼第一行。

讓我們來看看用手動執行器來驅動 Generator 的過程。整個過程從紫 ① 代碼 g = gen() 執行開始,到紫 ④ 結束。我在圖 3 中詳細標注了每一次 g.next() 的調用所引發的代碼執行權的更替以及 Generator 函數的暫停和恢復情況,還有 next() 調用的返回值。

在看這個時序圖的時候,希望你能注意到下面幾個細節:

  • 紫 ② 至 紫 ④ 每一次對 next() 的調用都意味著手動執行器把代碼執行權交還給了 Generator 。而當 next() 調用返回后,意味著手動執行器又獲得了代碼執行權。
  • 紫 ② 處代碼 g.next()? 執行所得到的 value 的數據類型是一個 Promise 對象 a 。所以調用者需要對其調用 then(onResolved) 并等待 onResolved 被執行。
  • 紫 ③ 處代碼是在紫 ② 所設置的 onResolved callback 里執行的。這意味著只有當 Promise 對象 a 的狀態轉換完成,Generator 才有機會拿到執行權并繼續往前執行。
  • 紫 ③ 處代碼 g.next(data)? 執行的時候,傳入了一個 data 。這意味著當 Generator 重新獲得執行權后,右側黃 ② 處的變量 a1 的值為 data 。我們來仔細想一下,data 是從哪里冒出來的呢?首先:右側黃 ② 處, yield 表達式 Promise 對象 a 先通過迭代器的遍歷回傳到了左側紫 ② 處;然后:在 Promise a 的 executor 里執行 resolve(data)? 后,data 出現了;最后:再通過 next(data)? 的方式注入到 Generator ,改變了黃 ② 處 yield 語句的返回值,也就把 data 交到了變量 a1 的手上 。這真是一個非常巧妙的過程。通過這樣的過程,我們既利用前面所說的 Generator 的特征控制住了右側代碼的執行節奏,還把左側代碼的執行結果帶回給了右側。右側黃 ② 處的代碼,如果我們把 yield 改成 await ,剛才所說的過程是不是就實現了 await 的語義??
  • 紫 ④ 處代碼和紫 ③ 類似,我就不細說了。

圖片

圖 3:手動執行器驅動 Generator 時序圖

4、自動執行器

上面的手動執行器用來解釋 Generator 的執行過程可以,但沒有實用功能,因為 Generator 里面有多少個 yield 語句,就得手寫對應個數的 .value.then() ,想想就覺得很累。所以搞一個可以無視 Generator 里面 yield 語句個數的自動執行器很有必要。

圖 5 右側就是這樣的自動執行器。代碼源自阮一峰的《ECMAScript 6 入門》。執行器的入口是右側紫 ⑦ 。很容易看懂,我就不多講了。

通過這樣的自動執行器,我們可以驅動任意一個 Generator 函數,并在執行權利的左、右側交換之間得到所需的數據。

圖片

圖 5:Genetaror + 自動執行器

5、async / await

恭喜你,堅持到現在還沒有放棄。我們離終點不遠啦。

async 函數其實是 Generator 函數的語法糖。那它到底是如何給 Generator 包裹上了糖衣并投喂給我們的呢?且看圖 6 。

最右側的 async 函數和最左側的 Generator 在代碼結構上沒有任何區別,只是把關鍵詞 function * 替換成了 async function ,把 yield 替換成了 await 。通常情況下我們是 async/await 搭配使用的,await 只能用于 wait 一個 Promise 對象,所以 yield 表達式部分也是一個 Promise 對象。因為 Generator 沒法自己執行的緣故,所以再搭配一個自動執行器。

看到這里,你是不是猛然理解了:為什么 await 的目標必須是一個 Promise 對象(如果目標是原始類型的值如數值、字符串和布爾值等,會被自動轉成立即 resolved 的 Promise 對象)?

圖片

圖 6:async/await = Promise + Generator + 自動執行器

6、代碼再回首

寫到這里,讓二哥來做一個總結:

async 函數本質上就是一個 Generator 函數,自動執行器和 Generator 的合作過程其實就是不斷操作各種 Promise 對象的過程,而 Promise 對象又完整地基于圖 1 所示的 event-loop 在工作。

好了,我們再來看看??上一篇??開頭處的那段代碼。whileLoop_1() 和 whileLoop2() 這兩個函數都是 async 函數。將其抽絲剝繭后,我們會發現它們其實就是分別在 LINE-A 處和 LINE-B 處產生了異步請求。對于主線程而言,這樣的異步請求不會影響它繼續執行其它的 JS code,所以我們能看到 CPU 不會陷入這兩個死循環中的任意一個。

'use strict';
async function sleep(intervalInMS)
{
return new Promise((resolve,reject)=>{
setTimeout(resolve,intervalInMS);
});
}
async function whileLoop_1(){
while(true){
try {
console.log('new round of whileLoop_1');
await sleep(1000); // LINE-A
continue;
} catch (error) {
// ...
}
console.log('end of whileLoop_1');
}
}
async function whileLoop_2(){
while(true){
try {
console.log('new round of whileLoop_2');
await sleep(1000); // LINE-B
continue;
} catch (error) {
// ...
}
console.log('end of whileLoop_2`');
}
}
whileLoop_1(); // LINE-C
whileLoop_2(); // LINE-D

我們看到無論是最早的 callback 還是 Promise, 再到 async/await 本質上都是異步編程模型,它們都是在充分利用 Node.js 的 event-loop 這個最核心的、最基礎的架構,最大化地提高并發度以提高系統資源利用率,同時在對程序員的編程友好度上也在不斷地提升。

Node.js 的 event-loop 這個架構是典型的事件驅動架構( event-driven architecture)。我們停下手中忙不完的工作,思考一下軟件運行的意義,梳理一下軟件開發模式的演進歷程,會發現無論是早期的單體巨石(monolithic)架構還是面向服務架構(service-oriented architecture),再到現在紅到發紫的微服務架構(microservice architecture),它們存在的意義以及進化的目的一直都沒有改變,那就是:盡一切可能,響應事件。

責任編輯:姜華 來源: 二哥聊云原生
相關推薦

2021-10-03 15:10:54

reduxsagaresolve

2022-04-29 08:41:40

開發應用程序執行器

2024-12-04 10:47:26

2022-05-05 08:43:22

SQL執行器參數

2023-10-08 10:21:11

JavaScriptAsync

2025-07-03 00:28:41

2009-04-15 19:12:31

2023-08-24 10:24:54

GitLabPodman

2017-07-13 17:00:17

內置執行器開發

2020-10-23 10:10:59

Promise前端代碼

2016-11-04 13:00:55

Asynces6Javascript

2021-07-21 10:48:03

物聯網傳感器執行器

2020-10-16 08:26:07

JavaScript開發技術

2025-07-21 05:00:00

if-elseV1版本

2021-08-18 07:05:57

ES6Asyncawait

2017-04-10 15:57:10

AsyncAwaitPromise

2009-09-09 12:10:40

2024-06-28 11:39:21

2024-12-17 00:00:00

Spring線程

2023-03-29 10:19:44

異步編程AsyncPromise
點贊
收藏

51CTO技術棧公眾號

你懂的一区二区| 神马电影网我不卡| 成人永久aaa| 992tv在线成人免费观看| aaaaaav| 向日葵视频成人app网址| 国产精品久久久久久久久久久免费看| 91欧美激情另类亚洲| 强行糟蹋人妻hd中文| 色吊丝一区二区| 欧美精品一二三| 欧美精品久久久久久久自慰| 男人av在线| 久久er精品视频| 久久久免费观看视频| 亚洲av片不卡无码久久| 国产一区一区| 日本久久电影网| 久久久久久久9| 可以免费看污视频的网站在线| 国产一区欧美日韩| 国产成人91久久精品| 九九热精品免费视频| 精品视频免费| 日韩av网站在线| 国产又粗又猛大又黄又爽| free性护士videos欧美| 亚洲欧美国产三级| 天堂精品视频| 人操人视频在线观看| 国产精品白丝jk黑袜喷水| 国产精品欧美一区二区| 亚洲久久在线观看| 黄色av成人| 欧美精品亚州精品| 国产午夜精品福利视频| 亚洲天堂日韩在线| 亚洲精品不卡在线| 又黄又爽又色的视频| 欧美视频第一| 欧美中文字幕久久| 国产免费人做人爱午夜视频| 高清视频在线观看三级| 亚洲午夜三级在线| 激情五月六月婷婷| 三级网站视频在在线播放| 中文字幕一区二区三区乱码在线| 午夜精品区一区二区三| 久久经典视频| 久久久久久久久免费| 久久99精品久久久久久秒播放器 | 国产精品国产三级国产专播精品人| 欧美日韩成人免费观看| 中文字幕一区二区三区乱码图片| 日韩中文在线不卡| 任你操精品视频| 日韩在线不卡| 久久精品99久久香蕉国产色戒| 国产农村妇女精品一区| 手机在线电影一区| 日韩综合视频在线观看| 无码黑人精品一区二区| 91精品一区二区三区综合| 久久精品夜夜夜夜夜久久| 久久成人小视频| 亚洲天堂一区二区三区四区| 欧美成人高清视频| 久久久久免费看| 亚洲国产精品第一区二区三区| 欧美精品18videosex性欧美| 国产一级aa大片毛片| 亚洲高清久久| 日韩免费高清在线观看| 中日韩av在线| 国产精品一级片| 国产一区二区中文字幕免费看| 五月婷婷久久久| 久久久精品国产免大香伊| 日韩hmxxxx| 免费av在线网址| 一区二区三区视频在线看| av免费观看国产| 亚洲成人短视频| 538prom精品视频线放| 国产精品二区视频| av日韩在线播放| 亚洲欧美另类国产| 国产麻豆视频在线观看| 激情亚洲成人| 国产精品久久视频| www.成人精品| 久久精品欧美一区二区三区不卡 | 国产艳妇疯狂做爰视频| 亚洲精品小区久久久久久| 日韩在线观看你懂的| 九九免费精品视频| 日韩高清一区二区| 99国产在线视频| 户外极限露出调教在线视频| 亚洲男人天堂av网| 亚洲色成人一区二区三区小说| 国产一区二区三区影视| 日韩欧美一区二区久久婷婷| 亚洲熟妇无码av| 亚洲综合专区| 全球成人中文在线| 精品人妻一区二区三区浪潮在线 | 久久久久黄色片| 日韩中文字幕亚洲一区二区va在线| 91麻豆桃色免费看| 欧美精品久久久久久久久久丰满| 日韩毛片高清在线播放| 黄色影院一级片| 日韩高清一区| 中文字幕欧美日韩| 黑人一级大毛片| 国产福利一区二区| 亚洲欧美日韩国产yyy| 韩日毛片在线观看| 日韩欧美成人一区| 一本一本久久a久久| 老司机精品视频网站| av一区二区三区在线观看| 91视频在线观看| 色综合久久中文字幕| 日本成人在线免费| 91综合网人人| 国产精品久久久久久搜索 | 妞干网在线观看视频| www一区二区三区| 在线观看国产精品日韩av| 国产成人无码精品| 成人免费av网站| 中文字幕色呦呦| 亚洲电影二区| 日韩最新中文字幕电影免费看| 亚洲乱码国产乱码精品| 成人激情午夜影院| 成年丰满熟妇午夜免费视频| 亚洲国产91视频| 波霸ol色综合久久| 亚洲最大成人在线视频| 国产欧美日韩不卡免费| 成人免费视频久久| 神马电影久久| 国产成人av在线| 日韩a级作爱片一二三区免费观看| 亚洲午夜久久久| 性折磨bdsm欧美激情另类| 亚洲综合中文| 都市激情久久久久久久久久久| a毛片在线观看| 91精品国产综合久久久久久漫画| 婷婷国产成人精品视频| 麻豆视频观看网址久久| 亚洲精品日韩成人| 香蕉久久一区| 欧美大片网站在线观看| 亚洲国产成人在线观看| 亚洲一区二区三区四区五区黄| 51自拍视频在线观看| 欧美精品观看| 国产女人水真多18毛片18精品| 爱福利在线视频| 日韩高清免费在线| aaa在线视频| 国产精品国产a| 在线观看日本www| 在线看片不卡| 国产女主播一区二区| 无遮挡爽大片在线观看视频 | 岛国成人毛片| 欧美mv日韩mv| 日韩在线 中文字幕| 国产精品网曝门| 亚洲免费在线播放视频| 黄色成人精品网站| 欧美精品国产精品久久久| 福利一区二区三区视频在线观看| 久久亚洲精品一区| 色丁香婷婷综合久久| 91国产福利在线| 四虎精品免费视频| 不卡av免费在线观看| 久久精品网站视频| 欧美日本二区| 日本一区二区久久精品| 大胆国模一区二区三区| 久久久久中文字幕| a中文在线播放| 精品国产亚洲在线| 日本丰满少妇做爰爽爽| 一区二区高清免费观看影视大全 | 日韩成人午夜| 国产欧美一区二区白浆黑人| 成人超碰在线| 在线播放国产一区中文字幕剧情欧美| 国产男男gay体育生白袜| 精品福利樱桃av导航| 影音先锋男人看片资源| 成人aaaa免费全部观看| 国产精品区在线| 99热在线精品观看| 一区二区三区三区在线| 久久99偷拍| 91欧美激情另类亚洲| 偷拍中文亚洲欧美动漫| 欧美高清videos高潮hd| 北条麻妃在线| 亚洲精品成人av| 国产黄色高清视频| 欧美在线不卡视频| 日韩黄色精品视频| 亚洲婷婷在线视频| 最近中文字幕在线mv视频在线 | 中日韩精品一区二区三区| 国产在线播精品第三| 无码日韩人妻精品久久蜜桃| 一区视频在线看| 天堂av免费看| 日韩久久视频| 日本免费高清不卡| 久久a爱视频| 国产精品青青草| 精品国产一区二| 国产美女精彩久久| 小黄鸭精品aⅴ导航网站入口| 亚洲**2019国产| 美足av综合网| 欧美老女人xx| av在线导航| 成年无码av片在线| 日本蜜桃在线观看| 一区二区亚洲欧洲国产日韩| 蜜桃视频在线播放| 日韩成人中文字幕在线观看| 成人乱码一区二区三区| 欧美一区二区大片| 国产精品人妻一区二区三区| 欧美日韩午夜精品| 一区二区三区在线免费观看视频| 色综合久久88色综合天天| 国产专区第一页| 精品久久久久久亚洲国产300| 国产亚洲精品女人久久久久久| 亚洲在线视频一区| 麻豆视频在线观看| 亚洲电影中文字幕在线观看| 久久久香蕉视频| 亚洲国产精品久久艾草纯爱| 国产一级在线观看视频| 亚洲国产精品一区二区久久恐怖片| 国产av无码专区亚洲av毛网站| 亚洲人成网站影音先锋播放| 翔田千里88av中文字幕| 一区二区三区91| 国产在线成人精品午夜| 午夜成人免费视频| 国产精品久久久久久99| 精品欧美aⅴ在线网站| 日本特级黄色片| 欧洲精品一区二区| 国产乱叫456在线| 日韩欧美亚洲国产精品字幕久久久| 99riav国产| 亚洲精品电影网| 黄色大片在线看| 日韩中文娱乐网| 欧美1—12sexvideos| 韩国视频理论视频久久| 成人影院网站| 成人乱人伦精品视频在线观看| 国产精品白丝久久av网站| 国产精品v欧美精品v日韩精品| 久久大胆人体视频| 日本成人黄色| 亚洲一区二区三区| 97超碰在线人人| 日本成人在线电影网| 日日夜夜精品视频免费观看| 99久久综合精品| 成年人看的免费视频| 一区二区欧美视频| 国产美女www| 欧美一级日韩免费不卡| 手机福利小视频在线播放| 在线观看国产欧美| 爱福利在线视频| 国产欧美日韩免费| 久久精品论坛| 一区二区精品在线观看| 亚洲国产免费看| 91高清国产视频| 不卡免费追剧大全电视剧网站| 欧美xxxx精品| 欧美午夜视频一区二区| 夜夜躁狠狠躁日日躁av| 日韩av在线资源| 国产盗摄在线观看| 国产91网红主播在线观看| 国产麻豆精品| 日本一区免费看| 黄色欧美成人| 欧美成人乱码一二三四区免费| av不卡免费在线观看| 四虎884aa成人精品| 日韩欧美精品免费在线| 亚洲国产中文字幕在线| 在线看欧美日韩| 蜜臀久久精品| 成人欧美一区二区| 99精品电影| 97公开免费视频| 91在线看国产| 黄页网站免费观看| 欧美日韩国产精选| 免费福利在线观看| 69av在线播放| 91欧美极品| 成人性做爰片免费视频| 日韩精品亚洲专区| 波多野结衣 在线| 亚洲超丰满肉感bbw| 国产www视频| 精品国产一区二区在线| 精品成人av| 欧美日韩精品免费看| 亚洲深夜激情| 波多野结衣加勒比| 亚洲综合偷拍欧美一区色| 人妻换人妻仑乱| 久久久久久亚洲综合影院红桃 | 欧美成人有码| 免费成年人高清视频| 欧美激情一区在线观看| jizz国产在线观看| 亚洲色图50p| 成人福利av| 欧美日韩一区在线播放| 99热精品在线观看| 亚洲蜜桃精久久久久久久久久久久| 亚洲午夜久久久久久久久电影网| 亚洲av无码一区二区三区dv| 欧美老少配视频| 97se亚洲国产一区二区三区| 免费的av在线| 国产传媒久久文化传媒| 青春草免费视频| 精品sm捆绑视频| 欧美videossex另类| 国产成人精品自拍| 亚洲日韩视频| 久久久无码人妻精品一区| 欧美色道久久88综合亚洲精品| 蜜桃视频污在线观看| 国内精品小视频| 日本在线中文字幕一区| 女人天堂av手机在线| 久久久91精品国产一区二区三区| www.国产毛片| 中文字幕亚洲情99在线| 亚洲欧美一级| 妞干网视频在线观看| 97精品视频在线观看自产线路二| 香蕉影院在线观看| 在线亚洲男人天堂| 国产精品美女久久久久| 人妻av无码专区| 久久综合久久久久88| 中日韩在线观看视频| 久久偷看各类女兵18女厕嘘嘘| 一区二区三区在线资源| jizzjizzxxxx| 国产精品美女www爽爽爽| 国产成人精品无码高潮| 97av在线视频| 成人免费看片39| 亚洲综合中文网| 日韩欧美福利视频| 美女免费久久| 精品国产_亚洲人成在线| 日产国产欧美视频一区精品| 粉嫩av性色av蜜臀av网站| 亚洲国产精品人久久电影| 亚洲国产尤物| 久草免费福利在线| 欧美极品aⅴ影院| 性色av蜜臀av| 国产精品99久久久久久www| 1024精品久久久久久久久| 亚洲第一黄色网址| 欧美高清性hdvideosex| 国产高清视频色在线www| 五月天综合网| 99国产精品久久久久久久久久久| 中文字幕欧美人妻精品| 久久久亚洲精品视频| 久久人人99| 37p粉嫩大胆色噜噜噜| 日韩一区二区视频在线观看|