久久精品中文字幕av,av.涩涩涩涩涩涩涩涩,亚洲国产日韩欧美精品成人久久久,成人福利电影免费在线观看,日产国产原创av,日韩av午夜激情,bt天堂中文字幕,超级碰人妻在线视频,欧美老熟妇久久一区二区

??一站式輕松地調(diào)用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
[TOC] # 特百惠 (譯者注:特百惠是美國家居用品品牌,代表產(chǎn)品是塑料容器。) ## 強大的容器 ![jar](https://box.kancloud.cn/c9d199b41ab6dcd64b9eedf19a8fccaf_362x514.png) 我們已經(jīng)知道如何書寫函數(shù)式的程序了,即通過管道把數(shù)據(jù)在一系列純函數(shù)間傳遞的程序。我們也知道了,這些程序就是聲明式的行為規(guī)范。但是,控制流(control flow)、異常處理(error handling)、異步操作(asynchronous actions)和狀態(tài)(state)呢?還有更棘手的作用(effects)呢?本章將對上述這些抽象概念賴以建立的基礎(chǔ)作一番探究。 首先我們將創(chuàng)建一個容器(container)。這個容器必須能夠裝載任意類型的值;否則的話,像只能裝木薯布丁的密封塑料袋是沒什么用的。這個容器將會是一個對象,但我們不會為它添加面向?qū)ο笥^念下的屬性和方法。是的,我們將把它當(dāng)作一個百寶箱——一個存放寶貴的數(shù)據(jù)的特殊盒子。 ```js var Container = function(x) { this.__value = x; } Container.of = function(x) { return new Container(x); }; ``` 這是本書的第一個容器,我們貼心地把它命名為 `Container`。我們將使用 `Container.of` 作為構(gòu)造器(constructor),這樣就不用到處去寫糟糕的 `new` 關(guān)鍵字了,非常省心。實際上不能這么簡單地看待 `of` 函數(shù),但暫時先認(rèn)為它是把值放到容器里的一種方式。 我們來檢驗下這個嶄新的盒子: ```js Container.of(3) //=> Container(3) Container.of("hotdogs") //=> Container("hotdogs") Container.of(Container.of({name: "yoda"})) //=> Container(Container({name: "yoda" })) ``` 如果用的是 node,那么你會看到打印出來的是 `{__value: x}`,而不是實際值 `Container(x)`;Chrome 打印出來的是正確的。不過這并不重要,只要你理解 `Container` 是什么樣的就行了。有些環(huán)境下,你也可以重寫 `inspect` 方法,但我們不打算涉及這方面的知識。在本書中,出于教學(xué)和美學(xué)上的考慮,我們將把概念性的輸出都寫成好像 `inspect` 被重寫了的樣子,因為這樣寫的教育意義將遠遠大于 `{__value: x}`。 在繼續(xù)后面的內(nèi)容之前,先澄清幾點: * `Container` 是個只有一個屬性的對象。盡管容器可以有不止一個的屬性,但大多數(shù)容器還是只有一個。我們很隨意地把 `Container` 的這個屬性命名為 `__value`。 * `__value` 不能是某個特定的類型,不然 `Container` 就對不起它這個名字了。 * 數(shù)據(jù)一旦存放到 `Container`,就會一直待在那兒。我們*可以*用 `.__value` 獲取到數(shù)據(jù),但這樣做有悖初衷。 如果把容器想象成玻璃罐的話,上面這三條陳述的理由就會比較清晰了。但是暫時,請先保持耐心。 ## 第一個 functor 一旦容器里有了值,不管這個值是什么,我們就需要一種方法來讓別的函數(shù)能夠操作它。 ```js // (a -> b) -> Container a -> Container b Container.prototype.map = function(f){ return Container.of(f(this.__value)) } ``` 這個 `map` 跟數(shù)組那個著名的 `map` 一樣,除了前者的參數(shù)是 `Container a` 而后者是 `[a]`。它們的使用方式也幾乎一致: ```js Container.of(2).map(function(two){ return two + 2 }) //=> Container(4) Container.of("flamethrowers").map(function(s){ return s.toUpperCase() }) //=> Container("FLAMETHROWERS") Container.of("bombs").map(concat(' away')).map(_.prop('length')) //=> Container(10) ``` 為什么要使用這樣一種方法?因為我們能夠在不離開 `Container` 的情況下操作容器里面的值。這是非常了不起的一件事情。`Container` 里的值傳遞給 `map` 函數(shù)之后,就可以任我們操作;操作結(jié)束后,為了防止意外再把它放回它所屬的 `Container`。這樣做的結(jié)果是,我們能連續(xù)地調(diào)用 `map`,運行任何我們想運行的函數(shù)。甚至還可以改變值的類型,就像上面最后一個例子中那樣。 等等,如果我們能一直調(diào)用 `map`,那它不就是個組合(composition)么!這里邊是有什么數(shù)學(xué)魔法在起作用?是 *functor*。各位,這個數(shù)學(xué)魔法就是 *functor*。 > functor 是實現(xiàn)了 `map` 函數(shù)并遵守一些特定規(guī)則的容器類型。 沒錯,*functor* 就是一個簽了合約的接口。我們本來可以簡單地把它稱為 `Mappable`,但現(xiàn)在為時已晚,哪怕 *functor* 一點也不 *fun*。functor 是范疇學(xué)里的概念,我們將在本章末尾詳細(xì)探索與此相關(guān)的數(shù)學(xué)知識;暫時我們先用這個名字很奇怪的接口做一些不那么理論的、實用性的練習(xí)。 把值裝進一個容器,而且只能使用 `map` 來處理它,這么做的理由到底是什么呢?如果我們換種方式來問,答案就很明顯了:讓容器自己去運用函數(shù)能給我們帶來什么好處?答案是抽象,對于函數(shù)運用的抽象。當(dāng) `map` 一個函數(shù)的時候,我們請求容器來運行這個函數(shù)。不夸張地講,這是一種十分強大的理念。 ## 薛定諤的 Maybe ![cat](https://box.kancloud.cn/edf7a53f6b206cc4d021d92b0b9dad8e_190x190.png) 說實話 `Container` 挺無聊的,而且通常我們稱它為 `Identity`,與 `id` 函數(shù)的作用相同(這里也是有數(shù)學(xué)上的聯(lián)系的,我們會在適當(dāng)時候加以說明)。除此之外,還有另外一種 functor,那就是實現(xiàn)了 `map` 函數(shù)的類似容器的數(shù)據(jù)類型,這種 functor 在調(diào)用 `map` 的時候能夠提供非常有用的行為?,F(xiàn)在讓我們來定義一個這樣的 functor。 ```js var Maybe = function(x) { this.__value = x; } Maybe.of = function(x) { return new Maybe(x); } Maybe.prototype.isNothing = function() { return (this.__value === null || this.__value === undefined); } Maybe.prototype.map = function(f) { return this.isNothing() ? Maybe.of(null) : Maybe.of(f(this.__value)); } ``` `Maybe` 看起來跟 `Container` 非常類似,但是有一點不同:`Maybe` 會先檢查自己的值是否為空,然后才調(diào)用傳進來的函數(shù)。這樣我們在使用 `map` 的時候就能避免惱人的空值了(注意這個實現(xiàn)出于教學(xué)目的做了簡化)。 ```js Maybe.of("Malkovich Malkovich").map(match(/a/ig)); //=> Maybe(['a', 'a']) Maybe.of(null).map(match(/a/ig)); //=> Maybe(null) Maybe.of({name: "Boris"}).map(_.prop("age")).map(add(10)); //=> Maybe(null) Maybe.of({name: "Dinah", age: 14}).map(_.prop("age")).map(add(10)); //=> Maybe(24) ``` 注意看,當(dāng)傳給 `map` 的值是 `null` 時,代碼并沒有爆出錯誤。這是因為每一次 `Maybe` 要調(diào)用函數(shù)的時候,都會先檢查它自己的值是否為空。 這種點記法(dot notation syntax)已經(jīng)足夠函數(shù)式了,但是正如在第 1 部分指出的那樣,我們更想保持一種 pointfree 的風(fēng)格。碰巧的是,`map` 完全有能力以 curry 函數(shù)的方式來“代理”任何 functor: ```js // map :: Functor f => (a -> b) -> f a -> f b var map = curry(function(f, any_functor_at_all) { return any_functor_at_all.map(f); }); ``` 這樣我們就可以像平常一樣使用組合,同時也能正常使用 `map` 了,非常振奮人心。ramda 的 `map` 也是這樣。后面的章節(jié)中,我們將在點記法更有教育意義的時候使用點記法,在方便使用 pointfree 模式的時候就用 pointfree。你注意到了么?我在類型標(biāo)簽中偷偷引入了一個額外的標(biāo)記:`Functor f =>`。這個標(biāo)記告訴我們 `f` 必須是一個 functor。沒什么復(fù)雜的,但我覺得有必要提一下。 ## 用例 實際當(dāng)中,`Maybe` 最常用在那些可能會無法成功返回結(jié)果的函數(shù)中。 ```js // safeHead :: [a] -> Maybe(a) var safeHead = function(xs) { return Maybe.of(xs[0]); }; var streetName = compose(map(_.prop('street')), safeHead, _.prop('addresses')); streetName({addresses: []}); // Maybe(null) streetName({addresses: [{street: "Shady Ln.", number: 4201}]}); // Maybe("Shady Ln.") ``` `safeHead` 與一般的 `_.head` 類似,但是增加了類型安全保證。引入 `Maybe` 會發(fā)生一件非常有意思的事情,那就是我們被迫要與狡猾的 `null` 打交道了。`safeHead` 函數(shù)能夠誠實地預(yù)告它可能的失敗——失敗真沒什么可恥的——然后返回一個 `Maybe` 來通知我們相關(guān)信息。實際上不僅僅是*通知*,因為畢竟我們想要的值深藏在 `Maybe` 對象中,而且只能通過 `map` 來操作它。本質(zhì)上,這是一種由 `safeHead` 強制執(zhí)行的空值檢查。有了這種檢查,我們才能在夜里安然入睡,因為我們知道最不受人待見的 `null` 不會突然出現(xiàn)。類似這樣的 API 能夠把一個像紙糊起來的、脆弱的應(yīng)用升級為實實在在的、健壯的應(yīng)用,這樣的 API 保證了更加安全的軟件。 有時候函數(shù)可以明確返回一個 `Maybe(null)` 來表明失敗,例如: ```js // withdraw :: Number -> Account -> Maybe(Account) var withdraw = curry(function(amount, account) { return account.balance >= amount ? Maybe.of({balance: account.balance - amount}) : Maybe.of(null); }); // finishTransaction :: Account -> String var finishTransaction = compose(remainingBalance, updateLedger); // <- 假定這兩個函數(shù)已經(jīng)在別處定義好了 // getTwenty :: Account -> Maybe(String) var getTwenty = compose(map(finishTransaction), withdraw(20)); getTwenty({ balance: 200.00}); // Maybe("Your balance is $180.00") getTwenty({ balance: 10.00}); // Maybe(null) ``` 要是錢不夠,`withdraw` 就會對我們嗤之以鼻然后返回一個 `Maybe(null)`。`withdraw` 也顯示出了它的多變性,使得我們后續(xù)的操作只能用 `map` 來進行。這個例子與前面例子不同的地方在于,這里的 `null` 是有意的。我們不用 `Maybe(String)` ,而是用 `Maybe(null)` 來發(fā)送失敗的信號,這樣程序在收到信號后就能立刻停止執(zhí)行。這一點很重要:如果 `withdraw` 失敗了,`map` 就會切斷后續(xù)代碼的執(zhí)行,因為它根本就不會運行傳遞給它的函數(shù),即 `finishTransaction`。這正是預(yù)期的效果:如果取款失敗,我們并不想更新或者顯示賬戶余額。 ## 釋放容器里的值 人們經(jīng)常忽略的一個事實是:任何事物都有個最終盡頭。那些會產(chǎn)生作用的函數(shù),不管它們是發(fā)送 JSON 數(shù)據(jù),還是在屏幕上打印東西,還是更改文件系統(tǒng),還是別的什么,都要有一個結(jié)束。但是我們無法通過 `return` 把輸出傳遞到外部世界,必須要運行這樣或那樣的函數(shù)才能傳遞出去。關(guān)于這一點,可以借用禪宗公案的口吻來敘述:“如果一個程序運行之后沒有可觀察到的作用,那它到底運行了沒有?”?;蛘撸\行之后達到自身的目的了沒有?有可能它只是浪費了幾個 CPU 周期然后就去睡覺了... 應(yīng)用程序所做的工作就是獲取、更改和保存數(shù)據(jù)直到不再需要它們,對數(shù)據(jù)做這些操作的函數(shù)有可能被 `map` 調(diào)用,這樣的話數(shù)據(jù)就可以不用離開它溫暖舒適的容器。諷刺的是,有一種常見的錯誤就是試圖以各種方法刪除 `Maybe` 里的值,好像這個不確定的值是魔鬼,刪除它就能讓它突然顯形,然后一切罪惡都會得到寬恕似的(譯者注:此處原文應(yīng)該是源自圣經(jīng))。要知道,我們的值沒有完成它的使命,很有可能是其他代碼分支造成的。我們的代碼,就像薛定諤的貓一樣,在某個特定的時間點有兩種狀態(tài),而且應(yīng)該保持這種狀況不變直到最后一個函數(shù)為止。這樣,哪怕代碼有很多邏輯性的分支,也能保證一種線性的工作流。 不過,對容器里的值來說,還是有個逃生口可以出去。也就是說,如果我們想返回一個自定義的值然后還能繼續(xù)執(zhí)行后面的代碼的話,是可以做到的;要達到這一目的,可以借助一個幫助函數(shù) `maybe`: ```js // maybe :: b -> (a -> b) -> Maybe a -> b var maybe = curry(function(x, f, m) { return m.isNothing() ? x : f(m.__value); }); // getTwenty :: Account -> String var getTwenty = compose( maybe("You're broke!", finishTransaction), withdraw(20) ); getTwenty({ balance: 200.00}); // "Your balance is $180.00" getTwenty({ balance: 10.00}); // "You're broke!" ``` 這樣就可以要么返回一個靜態(tài)值(與 `finishTransaction` 返回值的類型一致),要么繼續(xù)愉快地在沒有 `Maybe` 的情況下完成交易。`maybe` 使我們得以避免普通 `map` 那種命令式的 `if/else` 語句:`if(x !== null) { return f(x) }`。 引入 `Maybe` 可能會在初期造成一些不適。Swift 和 Scala 用戶知道我在說什么,因為這兩門語言的核心庫里就有 `Maybe` 的概念,只不過偽裝成 `Option(al)` 罷了。被迫在任何情況下都進行空值檢查(甚至有些時候我們可以確定某個值不會為空),的確讓大部分人頭疼不已。然而隨著時間推移,空值檢查會成為第二本能,說不定你還會感激它提供的安全性呢。不管怎么說,空值檢查大多數(shù)時候都能防止在代碼邏輯上偷工減料,讓我們脫離危險。 編寫不安全的軟件就像用蠟筆小心翼翼地畫彩蛋,畫完之后把它們?nèi)拥酱蠼稚弦粯樱ㄗg者注:意思是彩蛋非常易于尋找。來源于復(fù)活節(jié)習(xí)俗,人們會藏起一些彩蛋讓孩子尋找),或者像用三只小豬警告過的材料蓋個養(yǎng)老院一樣(譯者注:來源于“三只小豬”童話故事)。`Maybe` 能夠非常有效地幫助我們增加函數(shù)的安全性。 有一點我必須要提及,否則就太不負(fù)責(zé)任了,那就是 `Maybe` 的“真正”實現(xiàn)會把它分為兩種類型:一種是非空值,另一種是空值。這種實現(xiàn)允許我們遵守 `map` 的 parametricity 特性,因此 `null` 和 `undefined` 能夠依然被 `map` 調(diào)用,functor 里的值所需的那種普遍性條件也能得到滿足。所以你會經(jīng)??吹?`Some(x) / None` 或者 `Just(x) / Nothing` 這樣的容器類型在做空值檢查,而不是 `Maybe`。 ## “純”錯誤處理 ![fists](https://box.kancloud.cn/71738d53117a08937158c385e44a7c4a_400x200.png) 說出來可能會讓你震驚,`throw/catch` 并不十分“純”。當(dāng)一個錯誤拋出的時候,我們沒有收到返回值,反而是得到了一個警告!拋錯的函數(shù)吐出一大堆的 0 和 1 作為盾和矛來攻擊我們,簡直就像是在反擊輸入值的入侵而進行的一場電子大作戰(zhàn)。有了 `Either` 這個新朋友,我們就能以一種比向輸入值宣戰(zhàn)好得多的方式來處理錯誤,那就是返回一條非常禮貌的消息作為回應(yīng)。我們來看一下: ```js var Left = function(x) { this.__value = x; } Left.of = function(x) { return new Left(x); } Left.prototype.map = function(f) { return this; } var Right = function(x) { this.__value = x; } Right.of = function(x) { return new Right(x); } Right.prototype.map = function(f) { return Right.of(f(this.__value)); } ``` `Left` 和 `Right` 是我們稱之為 `Either` 的抽象類型的兩個子類。我略去了創(chuàng)建 `Either` 父類的繁文縟節(jié),因為我們不會用到它的,但你了解一下也沒壞處。注意看,這里除了有兩個類型,沒別的新鮮東西。來看看它們是怎么運行的: ```js Right.of("rain").map(function(str){ return "b"+str; }); // Right("brain") Left.of("rain").map(function(str){ return "b"+str; }); // Left("rain") Right.of({host: 'localhost', port: 80}).map(_.prop('host')); // Right('localhost') Left.of("rolls eyes...").map(_.prop("host")); // Left('rolls eyes...') ``` `Left` 就像是青春期少年那樣無視我們要 `map` 它的請求。`Right` 的作用就像是一個 `Container`(也就是 Identity)。這里強大的地方在于,`Left` 有能力在它內(nèi)部嵌入一個錯誤消息。 假設(shè)有一個可能會失敗的函數(shù),就拿根據(jù)生日計算年齡來說好了。的確,我們可以用 `Maybe(null)` 來表示失敗并把程序引向另一個分支,但是這并沒有告訴我們太多信息。很有可能我們想知道失敗的原因是什么。用 `Either` 寫一個這樣的程序看看: ```js var moment = require('moment'); // getAge :: Date -> User -> Either(String, Number) var getAge = curry(function(now, user) { var birthdate = moment(user.birthdate, 'YYYY-MM-DD'); if(!birthdate.isValid()) return Left.of("Birth date could not be parsed"); return Right.of(now.diff(birthdate, 'years')); }); getAge(moment(), {birthdate: '2005-12-12'}); // Right(9) getAge(moment(), {birthdate: '20010704'}); // Left("Birth date could not be parsed") ``` 這么一來,就像 `Maybe(null)`,當(dāng)返回一個 `Left` 的時候就直接讓程序短路。跟 `Maybe(null)` 不同的是,現(xiàn)在我們對程序為何脫離原先軌道至少有了一點頭緒。有一件事要注意,這里返回的是 `Either(String, Number)`,意味著我們這個 `Either` 左邊的值是 `String`,右邊(譯者注:也就是正確的值)的值是 `Number`。這個類型簽名不是很正式,因為我們并沒有定義一個真正的 `Either` 父類;但我們還是從這個類型那里了解到不少東西。它告訴我們,我們得到的要么是一條錯誤消息,要么就是正確的年齡值。 ```js // fortune :: Number -> String var fortune = compose(concat("If you survive, you will be "), add(1)); // zoltar :: User -> Either(String, _) var zoltar = compose(map(console.log), map(fortune), getAge(moment())); zoltar({birthdate: '2005-12-12'}); // "If you survive, you will be 10" // Right(undefined) zoltar({birthdate: 'balloons!'}); // Left("Birth date could not be parsed") ``` 如果 `birthdate` 合法,這個程序就會把它神秘的命運打印在屏幕上讓我們見證;如果不合法,我們就會收到一個有著清清楚楚的錯誤消息的 `Left`,盡管這個消息是穩(wěn)穩(wěn)當(dāng)當(dāng)?shù)卮谒娜萜骼锏?。這種行為就像,雖然我們在拋錯,但是是以一種平靜溫和的方式拋錯,而不是像一個小孩子那樣,有什么不對勁就鬧脾氣大喊大叫。 在這個例子中,我們根據(jù) `birthdate` 的合法性來控制代碼的邏輯分支,同時又讓代碼進行從右到左的直線運動,而不用爬過各種條件語句的大括號。通常,我們不會把 `console.log` 放到 `zoltar` 函數(shù)里,而是在調(diào)用 `zoltar` 的時候才 `map` 它,不過本例中,讓你看看 `Right` 分支如何與 `Left` 不同也是很有幫助的。我們在 `Right` 分支的類型簽名中使用 `_` 表示一個應(yīng)該忽略的值(在有些瀏覽器中,你必須要 `console.log.bind(console)` 才能把 `console.log` 當(dāng)作一等公民使用)。 我想借此機會指出一件你可能沒注意到的事:這個例子中,盡管 `fortune` 使用了 `Either`,它對每一個 functor 到底要干什么卻是毫不知情的。前面例子中的 `finishTransaction` 也是一樣。通俗點來講,一個函數(shù)在調(diào)用的時候,如果被 `map` 包裹了,那么它就會從一個非 functor 函數(shù)轉(zhuǎn)換為一個 functor 函數(shù)。我們把這個過程叫做 *lift*。一般情況下,普通函數(shù)更適合操作普通的數(shù)據(jù)類型而不是容器類型,在必要的時候再通過 *lift* 變?yōu)楹线m的容器去操作容器類型。這樣做的好處是能得到更簡單、重用性更高的函數(shù),它們能夠隨需求而變,兼容任意 functor。 `Either` 并不僅僅只對合法性檢查這種一般性的錯誤作用非凡,對一些更嚴(yán)重的、能夠中斷程序執(zhí)行的錯誤比如文件丟失或者 socket 連接斷開等,`Either` 同樣效果顯著。你可以試試把前面例子中的 `Maybe` 替換為 `Either`,看怎么得到更好的反饋。 此刻我忍不住在想,我僅僅是把 `Either` 當(dāng)作一個錯誤消息的容器介紹給你!這樣的介紹有失偏頗,它的能耐遠不止于此。比如,它表示了邏輯或(也就是 `||`)。再比如,它體現(xiàn)了范疇學(xué)里 *coproduct* 的概念,當(dāng)然本書不會涉及這方面的知識,但值得你去深入了解,因為這個概念有很多特性值得利用。還比如,它是標(biāo)準(zhǔn)的 sum type(或者叫不交并集,disjoint union of sets),因為它含有的所有可能的值的總數(shù)就是它包含的那兩種類型的總數(shù)(我知道這么說你聽不懂,沒關(guān)系,這里有一篇[非常棒的文章](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/sum-types)講述這個問題)。`Either` 能做的事情多著呢,但是作為一個 functor,我們就用它處理錯誤。 就像 `Maybe` 可以有個 `maybe` 一樣,`Either` 也可以有一個 `either`。兩者的用法類似,但 `either` 接受兩個函數(shù)(而不是一個)和一個靜態(tài)值為參數(shù)。這兩個函數(shù)的返回值類型一致: ```js // either :: (a -> c) -> (b -> c) -> Either a b -> c var either = curry(function(f, g, e) { switch(e.constructor) { case Left: return f(e.__value); case Right: return g(e.__value); } }); // zoltar :: User -> _ var zoltar = compose(console.log, either(id, fortune), getAge(moment())); zoltar({birthdate: '2005-12-12'}); // "If you survive, you will be 10" // undefined zoltar({birthdate: 'balloons!'}); // "Birth date could not be parsed" // undefined ``` 終于用了一回那個神秘的 `id` 函數(shù)!其實它就是簡單地復(fù)制了 `Left` 里的錯誤消息,然后把這個值傳給 `console.log` 而已。通過強制在 `getAge` 內(nèi)部進行錯誤處理,我們的算命程序更加健壯了。結(jié)果就是,要么告訴用戶一個殘酷的事實并像算命師那樣跟他擊掌,要么就繼續(xù)運行程序。好了,現(xiàn)在我們已經(jīng)準(zhǔn)備好去學(xué)習(xí)一個完全不同類型的 functor 了。 ## 王老先生有作用... (譯者注:原標(biāo)題是“Old McDonald had Effects...”,源于美國兒歌“Old McDonald Had a Farm”。) ![dominoes](https://box.kancloud.cn/6ee09fa5b703f3ad298177452a95921d_269x299.png) 在關(guān)于純函數(shù)的的那一章(即第 3 章)里,有一個很奇怪的例子。這個例子中的函數(shù)會產(chǎn)生副作用,但是我們通過把它包裹在另一個函數(shù)里的方式把它變得看起來像一個純函數(shù)。這里還有一個類似的例子: ```js // getFromStorage :: String -> (_ -> String) var getFromStorage = function(key) { return function() { return localStorage[key]; } } ``` 要是我們沒把 `getFromStorage` 包在另一個函數(shù)里,它的輸出值就是不定的,會隨外部環(huán)境變化而變化。有了這個結(jié)實的包裹函數(shù)(wrapper),同一個輸入就總能返回同一個輸出:一個從 `localStorage` 里取出某個特定的元素的函數(shù)。就這樣(也許再高唱幾句贊美圣母的贊歌)我們洗滌了心靈,一切都得到了寬恕。 然而,這并沒有多大的用處,你說是不是。就像是你收藏的全新未拆封的玩偶,不能拿出來玩有什么意思。所以要是能有辦法進到這個容器里面,拿到它藏在那兒的東西就好了...辦法是有的,請看 `IO`: ```js var IO = function(f) { this.__value = f; } IO.of = function(x) { return new IO(function() { return x; }); } IO.prototype.map = function(f) { return new IO(_.compose(f, this.__value)); } ``` `IO` 跟之前的 functor 不同的地方在于,它的 `__value` 總是一個函數(shù)。不過我們不把它當(dāng)作一個函數(shù)——實現(xiàn)的細(xì)節(jié)我們最好先不管。這里發(fā)生的事情跟我們在 `getFromStorage` 那里看到的一模一樣:`IO` 把非純執(zhí)行動作(impure action)捕獲到包裹函數(shù)里,目的是延遲執(zhí)行這個非純動作。就這一點而言,我們認(rèn)為 `IO` 包含的是被包裹的執(zhí)行動作的返回值,而不是包裹函數(shù)本身。這在 `of` 函數(shù)里很明顯:`IO(function(){ return x })` 僅僅是為了延遲執(zhí)行,其實我們得到的是 `IO(x)`。 來用用看: ```js // io_window_ :: IO Window var io_window = new IO(function(){ return window; }); io_window.map(function(win){ return win.innerWidth }); // IO(1430) io_window.map(_.prop('location')).map(_.prop('href')).map(split('/')); // IO(["http:", "", "localhost:8000", "blog", "posts"]) // $ :: String -> IO [DOM] var $ = function(selector) { return new IO(function(){ return document.querySelectorAll(selector); }); } $('#myDiv').map(head).map(function(div){ return div.innerHTML; }); // IO('I am some inner html') ``` 這里,`io_window` 是一個真正的 `IO`,我們可以直接對它使用 `map`。至于 `$`,則是一個函數(shù),調(diào)用后會返回一個 `IO`。我把這里的返回值都寫成了*概念性*的,這樣就更加直觀;不過實際的返回值是 `{ __value: [Function] }`。當(dāng)調(diào)用 `IO` 的 `map` 的時候,我們把傳進來的函數(shù)放在了 `map` 函數(shù)里的組合的最末端(也就是最左邊),反過來這個函數(shù)就成為了新的 `IO` 的新 `__value`,并繼續(xù)下去。傳給 `map` 的函數(shù)并沒有運行,我們只是把它們壓到一個“運行?!钡淖钅┒硕眩粋€函數(shù)緊挨著另一個函數(shù),就像小心擺放的多米諾骨牌一樣,讓人不敢輕易推倒。這種情形很容易叫人聯(lián)想起“四人幫”(譯者注:《設(shè)計模式》一書作者)提出的命令模式(command pattern)或者隊列(queue)。 花點時間找回你關(guān)于 functor 的直覺吧。把實現(xiàn)細(xì)節(jié)放在一邊不管,你應(yīng)該就能自然而然地對各種各樣的容器使用 `map` 了,不管它是多么奇特怪異。這種偽超自然的力量要歸功于 functor 的定律,我們將在本章末尾對此作一番探索。無論如何,我們終于可以在不犧牲代碼純粹性的情況下,隨意使用這些不純的值了。 好了,我們已經(jīng)把野獸關(guān)進了籠子。但是,在某一時刻還是要把它放出來。因為對 `IO` 調(diào)用 `map` 已經(jīng)積累了太多不純的操作,最后再運行它無疑會打破平靜。問題是在哪里,什么時候打開籠子的開關(guān)?而且有沒有可能我們只運行 `IO` 卻不讓不純的操作弄臟雙手?答案是可以的,只要把責(zé)任推到調(diào)用者身上就行了。我們的純代碼,盡管陰險狡詐詭計多端,但是卻始終保持一副清白無辜的模樣,反而是實際運行 `IO` 并產(chǎn)生了作用的調(diào)用者,背了黑鍋。來看一個具體的例子。 ```js ////// 純代碼庫: lib/params.js /////// // url :: IO String var url = new IO(function() { return window.location.href; }); // toPairs = String -> [[String]] var toPairs = compose(map(split('=')), split('&')); // params :: String -> [[String]] var params = compose(toPairs, last, split('?')); // findParam :: String -> IO Maybe [String] var findParam = function(key) { return map(compose(Maybe.of, filter(compose(eq(key), head)), params), url); }; ////// 非純調(diào)用代碼: main.js /////// // 調(diào)用 __value() 來運行它! findParam("searchTerm").__value(); // Maybe(['searchTerm', 'wafflehouse']) ``` lib/params.js 把 `url` 包裹在一個 `IO` 里,然后把這頭野獸傳給了調(diào)用者;一雙手保持的非常干凈。你可能也注意到了,我們把容器也“壓?!绷?,要知道創(chuàng)建一個 `IO(Maybe([x]))` 沒有任何不合理的地方。我們這個“棧”有三層 functor(`Array` 是最有資格成為 mappable 的容器類型),令人印象深刻。 有件事困擾我很久了,現(xiàn)在我必須得說出來:`IO` 的 `__value` 并不是它包含的值,也不是像兩個下劃線暗示那樣是一個私有屬性。`__value` 是手榴彈的彈栓,只應(yīng)該被調(diào)用者以最公開的方式拉動。為了提醒用戶它的變化無常,我們把它重命名為 `unsafePerformIO` 看看。 ```js var IO = function(f) { this.unsafePerformIO = f; } IO.prototype.map = function(f) { return new IO(_.compose(f, this.unsafePerformIO)); } ``` 看,這就好多了?,F(xiàn)在調(diào)用的代碼就變成了 `findParam("searchTerm").unsafePerformIO()`,對應(yīng)用程序的用戶(以及本書讀者)來說,這簡直就直白得不能再直白了。 `IO` 會成為一個忠誠的伴侶,幫助我們馴化那些狂野的非純操作。下一節(jié)我們將學(xué)習(xí)一種跟 `IO` 在精神上相似,但是用法上又千差萬別的類型。 ## 異步任務(wù) 回調(diào)(callback)是通往地獄的狹窄的螺旋階梯。它們是埃舍爾(譯者注:荷蘭版畫藝術(shù)家)設(shè)計的控制流??吹揭粋€個嵌套的回調(diào)擠在大小括號搭成的架子上,讓人不由自主地聯(lián)想到地牢里的靈薄獄(還能再低點么?。ㄗg者注:靈薄獄即 limbo,基督教中地獄邊緣之意)。光是想到這樣的回調(diào)就讓我幽閉恐怖癥發(fā)作了。不過別擔(dān)心,處理異步代碼,我們有一種更好的方式,它的名字以“F”開頭。 這種方式的內(nèi)部機制過于復(fù)雜,復(fù)雜得哪怕我唾沫橫飛也很難講清楚。所以我們就直接用 Quildreen Motta 的 [Folktale](http://folktalejs.org/) 里的 `Data.Task` (之前是 `Data.Future`)。來見證一些例子吧: ```js // Node readfile example: //======================= var fs = require('fs'); // readFile :: String -> Task(Error, JSON) var readFile = function(filename) { return new Task(function(reject, result) { fs.readFile(filename, 'utf-8', function(err, data) { err ? reject(err) : result(data); }); }); }; readFile("metamorphosis").map(split('\n')).map(head); // Task("One morning, as Gregor Samsa was waking up from anxious dreams, he discovered that // in bed he had been changed into a monstrous verminous bug.") // jQuery getJSON example: //======================== // getJSON :: String -> {} -> Task(Error, JSON) var getJSON = curry(function(url, params) { return new Task(function(reject, result) { $.getJSON(url, params, result).fail(reject); }); }); getJSON('/video', {id: 10}).map(_.prop('title')); // Task("Family Matters ep 15") // 傳入普通的實際值也沒問題 Task.of(3).map(function(three){ return three + 1 }); // Task(4) ``` 例子中的 `reject` 和 `result` 函數(shù)分別是失敗和成功的回調(diào)。正如你看到的,我們只是簡單地調(diào)用 `Task` 的 `map` 函數(shù),就能操作將來的值,好像這個值就在那兒似的。到現(xiàn)在 `map` 對你來說應(yīng)該不稀奇了。 如果熟悉 promise 的話,你該能認(rèn)出來 `map` 就是 `then`,`Task` 就是一個 promise。如果不熟悉你也不必氣餒,反正我們也不會用它,因為它并不純;但剛才的類比還是成立的。 與 `IO` 類似,`Task` 在我們給它綠燈之前是不會運行的。事實上,正因為它要等我們的命令,`IO` 實際就被納入到了 `Task` 名下,代表所有的異步操作——`readFile` 和 `getJSON` 并不需要一個額外的 `IO` 容器來變純。更重要的是,當(dāng)我們調(diào)用它的 `map` 的時候,`Task` 工作的方式與 `IO` 幾無差別:都是把對未來的操作的指示放在一個時間膠囊里,就像家務(wù)列表(chore chart)那樣——真是一種精密的拖延術(shù)。 我們必須調(diào)用 `fork` 方法才能運行 `Task`,這種機制與 `unsafePerformIO` 類似。但也有不同,不同之處就像 `fork` 這個名稱表明的那樣,它會 fork 一個子進程運行它接收到的參數(shù)代碼,其他部分的執(zhí)行不受影響,主線程也不會阻塞。當(dāng)然這種效果也可以用其他一些技術(shù)比如線程實現(xiàn),但這里的這種方法工作起來就像是一個普通的異步調(diào)用,而且 event loop 能夠不受影響地繼續(xù)運轉(zhuǎn)。我們來看一下 `fork`: ```js // Pure application //===================== // blogTemplate :: String // blogPage :: Posts -> HTML var blogPage = Handlebars.compile(blogTemplate); // renderPage :: Posts -> HTML var renderPage = compose(blogPage, sortBy('date')); // blog :: Params -> Task(Error, HTML) var blog = compose(map(renderPage), getJSON('/posts')); // Impure calling code //===================== blog({}).fork( function(error){ $("#error").html(error.message); }, function(page){ $("#main").html(page); } ); $('#spinner').show(); ``` 調(diào)用 `fork` 之后,`Task` 就趕緊跑去找一些文章,渲染到頁面上。與此同時,我們在頁面上展示一個 spinner,因為 `fork` 不會等收到響應(yīng)了才執(zhí)行它后面的代碼。最后,我們要么把文章展示在頁面上,要么就顯示一個出錯信息,視 `getJSON` 請求是否成功而定。 花點時間思考下這里的控制流為何是線性的。我們只需要從下讀到上,從右讀到左就能理解代碼,即便這段程序?qū)嶋H上會在執(zhí)行過程中到處跳來跳去。這種方式使得閱讀和理解應(yīng)用程序的代碼比那種要在各種回調(diào)和錯誤處理代碼塊之間跳躍的方式容易得多。 天哪,你看到了么,`Task` 居然也包含了 `Either`!沒辦法,為了能處理將來可能出現(xiàn)的錯誤,它必須得這么做,因為普通的控制流在異步的世界里不適用。這自然是好事一樁,因為它天然地提供了充分的“純”錯誤處理。 就算是有了 `Task`,`IO` 和 `Either` 這兩個 functor 也照樣能派上用場。待我舉個簡單例子向你說明一種更復(fù)雜、更假想的情況,雖然如此,這個例子還是能夠說明我的目的。 ```js // Postgres.connect :: Url -> IO DbConnection // runQuery :: DbConnection -> ResultSet // readFile :: String -> Task Error String // Pure application //===================== // dbUrl :: Config -> Either Error Url var dbUrl = function(c) { return (c.uname && c.pass && c.host && c.db) ? Right.of("db:pg://"+c.uname+":"+c.pass+"@"+c.host+"5432/"+c.db) : Left.of(Error("Invalid config!")); } // connectDb :: Config -> Either Error (IO DbConnection) var connectDb = compose(map(Postgres.connect), dbUrl); // getConfig :: Filename -> Task Error (Either Error (IO DbConnection)) var getConfig = compose(map(compose(connectDB, JSON.parse)), readFile); // Impure calling code //===================== getConfig("db.json").fork( logErr("couldn't read file"), either(console.log, map(runQuery)) ); ``` 這個例子中,我們在 `readFile` 成功的那個代碼分支里利用了 `Either` 和 `IO`。`Task` 處理異步讀取文件這一操作當(dāng)中的不“純”性,但是驗證 config 的合法性以及連接數(shù)據(jù)庫則分別使用了 `Either` 和 `IO`。所以你看,我們依然在同步地跟所有事物打交道。 例子我還可以再舉一些,但是就到此為止吧。這些概念就像 `map` 一樣簡單。 實際當(dāng)中,你很有可能在一個工作流中跑好幾個異步任務(wù),但我們還沒有完整學(xué)習(xí)容器的 api 來應(yīng)對這種情況。不必?fù)?dān)心,我們很快就會去學(xué)習(xí) monad 之類的概念。不過,在那之前,我們得先檢查下所有這些背后的數(shù)學(xué)知識。 ## 一點理論 前面提到,functor 的概念來自于范疇學(xué),并滿足一些定律。我們先來探索這些實用的定律。 ```js // identity map(id) === id; // composition compose(map(f), map(g)) === map(compose(f, g)); ``` *同一律*很簡單,但是也很重要。因為這些定律都是可運行的代碼,所以我們完全可以在我們自己的 functor 上試驗它們,驗證它們是否成立。 ```js var idLaw1 = map(id); var idLaw2 = id; idLaw1(Container.of(2)); //=> Container(2) idLaw2(Container.of(2)); //=> Container(2) ``` 看到?jīng)],它們是相等的。接下來看一看組合。 ```js var compLaw1 = compose(map(concat(" world")), map(concat(" cruel"))); var compLaw2 = map(compose(concat(" world"), concat(" cruel"))); compLaw1(Container.of("Goodbye")); //=> Container('Goodbye cruel world') compLaw2(Container.of("Goodbye")); //=> Container('Goodbye cruel world') ``` 在范疇學(xué)中,functor 接受一個范疇的對象和態(tài)射(morphism),然后把它們映射(map)到另一個范疇里去。根據(jù)定義,這個新范疇一定會有一個單位元(identity),也一定能夠組合態(tài)射;我們無須驗證這一點,前面提到的定律保證這些東西會在映射后得到保留。 可能我們關(guān)于范疇的定義還是有點模糊。你可以把范疇想象成一個有著多個對象的網(wǎng)絡(luò),對象之間靠態(tài)射連接。那么 functor 可以把一個范疇映射到另外一個,而且不會破壞原有的網(wǎng)絡(luò)。如果一個對象 `a` 屬于源范疇 `C`,那么通過 functor `F` 把 `a` 映射到目標(biāo)范疇 `D` 上之后,就可以使用 `F a` 來指代 `a` 對象(把這些字母拼起來是什么?!)??赡芸磮D會更容易理解: ![catmap](https://box.kancloud.cn/58cea3cfc6a72b16bc727a6bb2d021a7_450x292.png) 比如,`Maybe` 就把類型和函數(shù)的范疇映射到這樣一個范疇:即每個對象都有可能不存在,每個態(tài)射都有空值檢查的范疇。這個結(jié)果在代碼中的實現(xiàn)方式是用 `map` 包裹每一個函數(shù),用 functor 包裹每一個類型。這樣就能保證每個普通的類型和函數(shù)都能在新環(huán)境下繼續(xù)使用組合。從技術(shù)上講,代碼中的 functor 實際上是把范疇映射到了一個包含類型和函數(shù)的子范疇(sub category)上,使得這些 functor 成為了一種新的特殊的 endofunctor。但出于本書的目的,我們認(rèn)為它就是一個不同的范疇。 可以用一張圖來表示這種態(tài)射及其對象的映射: ![functormap](https://box.kancloud.cn/04242218dedce605b801d19a57411504_371x221.png) 這張圖除了能表示態(tài)射借助 functor `F` 完成從一個范疇到另一個范疇的映射之外,我們發(fā)現(xiàn)它還符合交換律,也就是說,順著箭頭的方向往前,形成的每一個路徑都指向同一個結(jié)果。不同的路徑意味著不同的行為,但最終都會得到同一個數(shù)據(jù)類型。這種形式化給了我們原則性的方式去思考代碼——無須分析和評估每一個單獨的場景,只管可以大膽地應(yīng)用公式即可。來看一個具體的例子。 ```js // topRoute :: String -> Maybe(String) var topRoute = compose(Maybe.of, reverse); // bottomRoute :: String -> Maybe(String) var bottomRoute = compose(map(reverse), Maybe.of); topRoute("hi"); // Maybe("ih") bottomRoute("hi"); // Maybe("ih") ``` 或者看圖: ![functormapmaybe](https://box.kancloud.cn/01a89329ac6a9882f2bb23abbeff349e_528x238.png) 根據(jù)所有 functor 都有的特性,我們可以立即理解代碼,重構(gòu)代碼。 functor 也能嵌套使用: ```js var nested = Task.of([Right.of("pillows"), Left.of("no sleep for you")]); map(map(map(toUpperCase)), nested); // Task([Right("PILLOWS"), Left("no sleep for you")]) ``` `nested` 是一個將來的數(shù)組,數(shù)組的元素有可能是程序拋出的錯誤。我們使用 `map` 剝開每一層的嵌套,然后對數(shù)組的元素調(diào)用傳遞進去的函數(shù)??梢钥吹?,這中間沒有回調(diào)、`if/else` 語句和 `for` 循環(huán),只有一個明確的上下文。的確,我們必須要 `map(map(map(f)))` 才能最終運行函數(shù)。不想這么做的話,可以組合 functor。是的,你沒聽錯: ```js var Compose = function(f_g_x){ this.getCompose = f_g_x; } Compose.prototype.map = function(f){ return new Compose(map(map(f), this.getCompose)); } var tmd = Task.of(Maybe.of("Rock over London")) var ctmd = new Compose(tmd); map(concat(", rock on, Chicago"), ctmd); // Compose(Task(Maybe("Rock over London, rock on, Chicago"))) ctmd.getCompose; // Task(Maybe("Rock over London, rock on, Chicago")) ``` 看,只有一個 `map`。functor 組合是符合結(jié)合律的,而且之前我們定義的 `Container` 實際上是一個叫 `Identity` 的 functor。identity 和可結(jié)合的組合也能產(chǎn)生一個范疇,這個特殊的范疇的對象是其他范疇,態(tài)射是 functor。這實在太傷腦筋了,所以我們不會深入這個問題,但是贊嘆一下這種模式的結(jié)構(gòu)性含義,或者它的簡單的抽象之美也是好的。 ## 總結(jié) 我們已經(jīng)認(rèn)識了幾個不同的 functor,但它們的數(shù)量其實是無限的。有一些值得注意的可迭代數(shù)據(jù)類型(iterable data structure)我們沒有介紹,像 tree、list、map 和 pair 等,以及所有你能說出來的。eventstream 和 observable 也都是 functor。其他的 functor 可能就是拿來做封裝或者僅僅是模擬類型。我們身邊到處都有 functor 的身影,本書也將會大量使用它們。 用多個 functor 參數(shù)調(diào)用一個函數(shù)怎么樣呢?處理一個由不純的或者異步的操作組成的有序序列怎么樣呢?要應(yīng)對這個什么都裝在盒子里的世界,目前我們工具箱里的工具還不全。下一章,我們將直奔 monad 而去。 [第 9 章: Monad](ch9.md) ## 練習(xí) ```js require('../../support'); var Task = require('data.task'); var _ = require('ramda'); // 練習(xí) 1 // ========== // 使用 _.add(x,y) 和 _.map(f,x) 創(chuàng)建一個能讓 functor 里的值增加的函數(shù) var ex1 = undefined //練習(xí) 2 // ========== // 使用 _.head 獲取列表的第一個元素 var xs = Identity.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'ti', 'do']); var ex2 = undefined // 練習(xí) 3 // ========== // 使用 safeProp 和 _.head 找到 user 的名字的首字母 var safeProp = _.curry(function (x, o) { return Maybe.of(o[x]); }); var user = { id: 2, name: "Albert" }; var ex3 = undefined // 練習(xí) 4 // ========== // 使用 Maybe 重寫 ex4,不要有 if 語句 var ex4 = function (n) { if (n) { return parseInt(n); } }; var ex4 = undefined // 練習(xí) 5 // ========== // 寫一個函數(shù),先 getPost 獲取一篇文章,然后 toUpperCase 讓這片文章標(biāo)題變?yōu)榇髮? // getPost :: Int -> Future({id: Int, title: String}) var getPost = function (i) { return new Task(function(rej, res) { setTimeout(function(){ res({id: i, title: 'Love them futures'}) }, 300) }); } var ex5 = undefined // 練習(xí) 6 // ========== // 寫一個函數(shù),使用 checkActive() 和 showWelcome() 分別允許訪問或返回錯誤 var showWelcome = _.compose(_.add( "Welcome "), _.prop('name')) var checkActive = function(user) { return user.active ? Right.of(user) : Left.of('Your account is not active') } var ex6 = undefined // 練習(xí) 7 // ========== // 寫一個驗證函數(shù),檢查參數(shù)是否 length > 3。如果是就返回 Right(x),否則就返回 // Left("You need > 3") var ex7 = function(x) { return undefined // <--- write me. (don't be pointfree) } // 練習(xí) 8 // ========== // 使用練習(xí) 7 的 ex7 和 Either 構(gòu)造一個 functor,如果一個 user 合法就保存它,否則 // 返回錯誤消息。別忘了 either 的兩個參數(shù)必須返回同一類型的數(shù)據(jù)。 var save = function(x){ return new IO(function(){ console.log("SAVED USER!"); return x + '-saved'; }); } var ex8 = undefined ```
67914熟女在线观看| 精品99国内中文字幕| 蜜桃一区二区三区大香蕉| 天天操天天干天天妻| 国产一区二区视频大全床| 中文字幕久久91| 亚洲乳大丰满中文字幕少妇av| av福利网站在线观看| 中文字幕一线一区和二区| 色播网站在线播放| 久久99精品久久久久久三级| 天堂av最新资源在线| 之久精品一区二区| 青青91免费视频| 亚洲 欧美 制服 人妻| 精品成人1区2区3区在线看片| 日韩成人av影视在线观看| 精品一区二区三区蜜桃臀的优势| 久久精品国产av网| 天天操,天天干,天天| 精品视频在线观看一区二区97| 久久精品视频在线国国| 免费色婷婷在线视频| 人妻少妇精品久久人妻| 亚洲av色图com| 一区二区三区内射美女毛片| 麻豆精品123在线观看| 丰满的人妻一区七区| 影音在线精品免费国产资源| 国产精品久久久久久吹吹潮| 青青草成人影院在线观看| 久久国产精品久久伊人麻豆 | 日韩欧美综合一区二区在线| 久久精品美国亚洲av伦理| 日日夜夜夜视频伊人久久 | 人人妻人人澡人人看| 日本久久久大片中文字幕| 国产日韩欧美成人一二三区| 日韩美女在线视频一区| 日韩视频在线播放一区二区| 日韩成人免费电影三区| 国产清纯白嫩美女无套| 日韩精品福利性无码专区| 久久婷婷亚洲中文一区二区| 久久久国产精品尤物av| 国产无av码在线观看| 午夜日韩麻豆福利| 热久久免费频精品18| 日韩精品在线视频播放| 久久久精品国产亚洲av网深田| 精品国产一区二区三区制服| 中文字幕av最新在线| 日韩福利视频在线看| 欧美日韩精品成人在线| 天天射天天舔天天射| 国产精品久久欠久久al换脸综合| 综合久久综合久久综合久久| 大香蕉大香蕉大香蕉大香蕉大| 国产91色在线i免费| 久久视频在线免费播放| 色yeye香蕉凹凸人妻三区| 丝袜日韩中文字幕| av传媒高清影院免费| 天天操天天爽天天舔天天操一操| 自拍偷拍亚洲欧美另类| 亚洲伊人网在线观看| 欧美日韩精品欧美日韩| 婷婷激情五月天图片| 青青草国产福利视频| 婷婷中文字幕色婷婷| 日韩av电影免费在线播放| 色播网站在线播放| 久久精品视频在线国国| 999热精品在线观看| 精品日韩偷拍欧美另类| 1024 国产高清の最新合集| av日韩中文字幕人妻| 激情黄色开心五月天| 国产三级三级三级三级av精品| 精品一区二区国产在线观看| 国产精品成人av麻豆| 久久久成人在线免费视频| 99爱99久久久久久久久久| 中文字幕版婷婷久久| 老鸭子在线观看免费播放| 精品视频在线观看一区二区97| 91中日在线中文字幕| 蜜臀av一区二区三区人妻少妇| 狠狠干中文字幕97视频| av福利网站在线观看| 欧美人妻系列,中文字幕 | 亚洲精选黄色在线观看| 亚洲欧美丝袜精品久久直播| 久久久亚洲熟妇熟女ⅹx| 久久久久国产精品夜夜夜| 另类欧美亚洲中文综合| 精品日韩偷拍欧美另类| 国产熟女高潮av77777| 久操免费福利在线视频观看视频| 麻豆视传媒官网直接进入免费观看| 日韩欧美颜色渔网| 国产一级av国产免费| 日韩欧美三级一区二区在线观看| av福利网站在线观看| 亚洲熟妇免费在线视频| 欧美日韩国产一级一顶级| 国产精品福利久久久久久久| 国产五月天在线观看视频| 日韩av电影免费在线播放| 另类蜜桃刺激视频在线观看| 日日夜夜夜视频伊人久久| 亚洲国产精品国自产拍av麻豆| 午夜在线看1000集| 安斋拉拉中文字幕在线| 丰满人妻一区二区三区视频看看| 久久草免费在线视频| 日韩精品少妇人妻熟女| 精品欧美日韩国产在线| 中文字幕人妻一区二区在线看| 精品人妻一区二区三区√| 欧美老熟妇重口另类xxx| 免费中文字幕在线播放| 欧美中文字幕久久久| 久久久亚洲熟妇熟女ⅹx| 午夜影院av在线| 亚洲精品网站成人久久综合| 久久久久久精品日韩| 精品人妻久久久久中文字幕19禁| 亚洲天堂av电影| 美女18禁久久久久麻豆| 91人妻露出精品在线| 人妻精品无码一区二区三区| 国产一区二区三区黄色| 欧美高清在线视频99| 99热这里只有的精品| 91嫩草17c欧美国产| 黄色片一级美女黄色片| 91人妻精品久久久久久久久| 亚洲国产精品五月天久久久| 亚洲最大成人网一区二区三区| 麻豆免费国产福利免费国产福利| 一级片一级片久久精品电影网电影 | 亚洲熟妇免费在线视频| 91免费av在线观看| 97人妻中文字幕精品视频| 97国产免费电影网| 免费看久久久久久久性大片| 日韩午夜激情福利免费| 国产av一区二区三区天美| 初撮日本五十路人妻| 久久久久久最新精品| 大尺度av一区二区三区| 亚洲欧美日韩一二三四五六七区| japanese 在线中文字幕| 日韩av电影com| 先锋资源站中文字幕| av福利网站在线观看| 久久精品美国亚洲av伦理| 人妻日韩精品在线观看视频| a级黄片在线免费观看| 蜜桃视频在线观看一区精品| 国产又大又猛又黄的视频| 国产日韩欧美人妻在线观看| 亚洲乳大丰满中文字幕少妇av| 亚洲 欧美 制服 人妻| 18在线观看久久久麻豆| 国产精品一区二区久久精品蜜臀 | 国产亚洲精久久久久久无码色戒| 免费精品国产日韩热久久| 最新偷窥偷拍免费视频观看| 国产欧美精品久久无广告| 日韩精品综合视频在线| 欧美亚洲av日韩综合一区| 日本东京热天天日天天干| 安斋拉拉中文字幕在线| 婷婷在线综合观看视频| 青青草久久大香蕉| 五月黄色激情视频| 日韩在线中文字幕不卡| 久久久久久精品日韩| 大香蕉大香蕉大香蕉大香蕉大| 国产成人无码AA精品一区| 亚洲综合在线伊人| 91人妻九色大屁股| 熟女人妻之中文字幕| www.色av成人| 伊人久久婷婷色综合98网| 午夜探花在线免费观看| 男人亚洲天堂2018| 亚洲激情熟女色图| 俺去鲁婷婷六月色综合| 日韩精品综合免费视频| www日本不卡一二三区| 欧美肥臀精品一区二区三区| 综合 另类 自拍| ass日本丰满熟妇pics| 97偷拍视频在线观看| 亚洲视频欧美视频另类| 久久热最新视频在线观看| 中文字幕的不卡人妻| 篠田优中文字幕在线播| 亚洲天堂黄色免费| 麻豆中文字幕av在线| 午夜精品福利小视频| 国产精品网址在线观看| 伊人久久婷婷色综合98网| 久久精品 中文字幕| 清纯唯美激情五月| 在线观看日韩中文| 婷婷在线综合观看视频| 国产精品久久欠久久al换脸综合| 色哟哟免费在线播放| 国产成人精品久久久女| 亚洲图色91东京热| 国产一区无码在线桃花| 亚洲精品一区二区三区丝袜| 久久一本麻豆天美欧美日韩| 国产一区二区不卡91| 一本色道久久亚洲综合精品蜜桃| 免费中文字幕在线播放| 在线观看日韩美视频一区| 在线观看视频 你懂得| 中文字幕在线视频亚洲| 国产69tv精品久久| 久久久久久久久久无吗| 欧美 国产 日韩 一区二区| 五月黄色激情视频| 青青草久久大香蕉| 日韩av电影在线观看的| 日韩av福利大片在线观看| 久久久久久夜夜夜精品国产| 日韩欧美在线视频第一页| 人妻熟女视频免费观看| 日本av熟女人妻| 日韩人妻插舔激情午夜 | 色哟哟视频在线观看国产| 蜜臀av日韩特黄大片| 在线人妻国产精品| 日本熟妇乱子伦a片在线观看 | 人人妻人人澡人人看| japanese 在线中文字幕| 国产乱子伦视频免费| av日韩在线免费观看网站 | 亚洲国产欧美日本视频| 色综合久久久久久久久| 99热这里只有精品网| 国产网址手机上可以看的国产网站 | 91高级会所在线播放| 久久精品国产91久久麻豆自制 | 国产欧美一区二区二区精品| 久久久久中文字幕免费久久久久久| 中文字幕一区二区不卡顿| 丰满人妻av白石茉莉奈电影| 亚洲 欧美 日本 国产| 国产精品亚洲精品成人| 久久久亚洲精品久久仙| 久久久久国产麻豆婷婷| 亚洲欧美日韩在线中文字幕小| 香蕉久久久久久久久久久久女| 天天色天天干天天舔| 国产a级片免费在线观看| 亚洲女人中文字幕在线| 精品人妻久久久久中文字幕19禁 | 久久久久久网站精品免费| 91久久亚洲成人精品| 精品人妻一区二区三区√| 蜜臀av 麻豆av| 激情黄色开心五月天| 久久99精品久久久久久三级| 亚洲精品久久久久久久久蜜桃| 国产av在线观看麻豆| 日韩色在线视频观看免费| 丰满人妻av白石茉莉奈电影| 热久久免费频精品18| 日韩av在线观看免费看看| 91国产手机视频在线观看| 国产精品久久久久久久久粉嫩av| 久久 99 精品视频| 久久 99 精品视频| 日韩欧美一级在线视频| 另类欧美亚洲中文综合| 日韩美女主播人体视频自拍首页| 中文字幕成人资源网站| 日韩欧美国产成人一区| 亚洲欧美自拍偷拍在线观看| 欧美中文字幕久久久| 欧美熟女人妻一区二区三区 | 在线中文免费黄色| 国产无av码在线观看| 欧美一区二区三区成人免费看| 国产精品99精品一区二区三区∴| youwu视频在线| 人妻一区二区中文字幕在线| 男人的天堂久久久亚洲| 日本黄页在线播放日本网站| www.199麻豆在线视频| 婷婷 少妇 av| 亚洲尺码和欧洲尺码av| 国产日韩av免费一区二区三区| 久久综合久久综合久久色| huangse网站在线观看| 国产 另类 在线 欧美日韩| 免费看久久久久久久性大片| 安斋拉拉中文字幕在线| 国产成人精品视频免费网站| 最新偷窥偷拍免费视频观看| 91啪啪啪内射网站| 久久热最新视频在线观看| 人妻办公室被强d在线电影| 五月爱婷婷六月丁香性| 日韩成人免费电影三区| 亚洲av网站女性向在线观看 | 国产一区二区三区女同| 欧美老熟妇重口另类xxx| 久久av资源男人站| 玖玖资源站中文字幕一区二区| 99九九99九九热视频| 日韩中文字幕在线网站| 亚洲精品乱码97久久久久久| 亚洲情欲大片在线观看| 亚洲国产精品成人精品软件| 蜜臀av日韩特黄大片| 人妻丰满精品一区二区三区| 亚洲人妻中文字幕av首页| 92视频影院视频影院麻豆| 日韩a视频在线播放视频| 久久最近最新中文字幕大全| 性欧美另类sex极品free| 中文字幕精品久久久人妻| 国产91久久久久久久| 欧美熟女高清视频一区二区| 天天操天天干天天做天天射| 日本高清不卡视频在线播放| 日韩欧美国产成人一区| 91在线播放视频免费| 日本熟妇人妻在线| av蜜臀懂色啊啊啊| 久久综合中文字幕一区二区三区| 亚洲尺码和欧洲尺码av| 亚洲欧洲av在线| 欧美自拍 亚洲偷拍| 亚洲青青青国产观看视频| 福利日韩精品中文字幕专区| 十八禁久久久久久久久久久久久久 | 色yeye香蕉凹凸人妻三区| 99爱99久久久久久久久久| 制服巨乳人妻在线| 日韩不卡一级成人免费视频| 成人精品一区一区二区看片| 大香蕉影视日本大香蕉97| 国产网址手机上可以看的国产网站 | 五月综合婷婷婷婷婷婷| 欧美自拍 亚洲偷拍| 人妻少妇精品久久人妻| 精品久久一区电影亚洲| 亚洲成年人电影天堂| 中文字幕人妻一区二区在线看| 日韩欧美激情入口| 日本少妇人妻xxxx| 国产精品色呦呦视频免费看| 92视频影院视频影院麻豆| 久久久久久久精品综合| 免费精品国产日韩热久久| 久久精品人妻中文字幕一区| 人人妻人人澡人人爽国产一区| 欧美日韩少妇一二三| 97网视频免费在线观看| 国产一区二区三区黄色| 亚洲天堂黄色在线| 国产三级三级三级三级av精品| 五月婷婷激情四射综合网| 欧美日韩综合国产精品| 亚洲熟妇av日韩熟妇在线| 精品日韩偷拍欧美另类| 日韩福利视频在线看| 婷婷激情五月天图片| 久久久久国产精品免费| 欧美日韩精品亚洲欧美| 欧美激情电影在线观看不卡| 欧美一区二区三区综合色| 国产日韩一区二区三区啪啪啪| 99热这里只有的精品| 伊人久久热青青草| 日韩av电影在线观看的| 欧美一区二区理论片在线观看 | 国产日韩欧美人妻在线观看| 国产青青91av在线视频| 国产99久久久国产精品成人免费| 亚洲综合在线伊人| 三级亚洲天堂亚洲天堂| 欧美性久久久久久久久久久| 91人妻人人妻人人爽| 日韩久久久三级电影| 日本黄页在线播放日本网站| 久久成人福利视频资源| 国产91色在线i免费| 亚洲 免费在线视频| 国产精品网址在线观看| 日本av男优巧克力| 欧美日韩精品综合在线一区二区| 亚洲成年人黄色片| 亚洲精品,欧美日韩| 日韩少妇视频在线直播| 日韩一区二区三区乱码| 亚洲国产精品综合久久2007| 欧美熟女vides| 中文字幕精品久久久人妻| 欧美aⅴ一区二区三区| 久久热最新视频在线观看| 久久久久久久久久久久久丰满| 欧美人妻a∨中文字幕在线| 国产亚洲av免费一区二区| 777亚洲精品乱码久久| 久久久久久少妇被弄高潮| 97人妻人人揉人人澡人人爽国产| 91沈先生探花极品在线| 午夜寻花美女在线| 99久久窝窝午夜影视| 自拍偷拍 亚洲 在线| 新版天堂av资源在线| 97精品久久人人爽人人爽| 麻豆精品一区在线免费观看| 亚洲综合色激情五月| 亚洲久久亚女同性| 中文字幕av久久爽爽| 日韩av午夜精品| japanese 在线中文字幕| 欧美自拍 亚洲偷拍| 男人亚洲天堂2018| 视频免费在线观看91| 麻豆精品123在线观看| 日韩av手机在线电影| 日韩有码视频在线免费观看| 久久精品琪琪男人的天堂| 玖玖资源站中文字幕一区二区| 久久久久久久久久性| 国产成人精品久久综合| 国产人妻另类综合专区| 欧美日韩成人三级在线| 亚洲成人影院中文字幕| 97人人人欧美人人妻人人| 天天色综合天天射综合| 亚洲激情 欧美激情| 日本午夜在线免费观看| 日韩中文字幕理伦| 中文字幕亚洲中文字幕| 国产一区二区三区女同| 欧美高清在线视频99| 日韩a毛片视频免费看| 午夜在线看1000集| 久久久久久久久久久久久熟女a∨| 国产又大又猛又黄的视频| 安斋拉拉中文字幕在线| 香蕉在线蕉久在线| 国产精品久久久久久xxx| 99爱99久久久久久久久久| 亚洲制服高清中文字幕| 中文字幕av最新资源| 91插插插操美女视频| 久久人妻久久人妻一区| 777亚洲精品乱码久久| 在线不卡日韩视频播放| 亚洲人妻中文字幕av首页| 麻豆视传媒官网直接进入免费观看| 人妻精品少妇嫩草麻豆| 97国产人妻换人妻| 欧美一区二区三区激情啪啪啪| 加勒比精品一区二区三区| 麻豆中文字幕av在线| 日韩精品少妇人妻熟女| 99精品高清免费在线视频| 午夜影院av在线| 国产日韩欧美春色另类小说| 日本精品久久久久中人妻| 日本久久久大片中文字幕| 日韩av中文网址| 日韩av在线精品观看| 精品一区二区国产在线观看| 亚洲av电影在线一区二区| 久久国产精品——国产精品 | 欧美一区二区精品人妻免费视频 | 免费麻豆国产一区二区三区| 无码人妻精品一区二区三区久久 | 色哟哟视频在线观看国产| 国产美女深喉口爆吞精免费| 国产剧情高清在线观看| 五月婷婷51视频免费| 天天色综合天天射综合| 日本熟妇人妻在线| 亚洲欧美自拍偷拍在线观看| 欧美日韩精品欧美日韩| 成年美女黄色av网站| 色婷婷国产熟妇人妻露脸| 欧美日韩人妻久久精品| 福利日韩精品中文字幕专区| 激情五月天狠婷婷| 91国产视频网站在线观看| av国产一区二区三区| 亚洲精品久久久久久久久蜜桃| 97精品国产自在在线观看蜜臀| 青青青青青欧美在线视频观看| 99.com精品视频| 日本美女大学生一区二区三区| 97精品国产自在在线观看蜜臀| www.199麻豆在线视频| 91中日在线中文字幕| 在线国产小视频麻豆| 视频免费在线观看91| 久久亚洲精品无码系列客服| 日韩国产精品电影网| 人妻丰满精品一区二区三区| 国产69tv精品久久| 99精品视频69v精品视频| 真实玩弄白嫩丰满人妻少妇三级| 亚洲欧美国产另类91综合| 日韩在线免费视频精品| 婷婷在线综合观看视频| 久久av资源男人站| 92视频影院视频影院麻豆| 久久av一区中文字幕| 亚洲女人中文字幕在线| 91麻豆免费国产在线| 9久久国产精品一区二区| 亚洲天堂黄色免费| 一本一道久久a久久久| 国产精品一二三四在线| 免费麻豆国产一区二区三区| 欧美人妻激情中文视频| 亚洲激情视频在线视频| huangse网站在线观看| 精品aa级中文字幕人妻| av国偷自产自拍自在线| 久久99久久com| 天天做天天舔天天射| 另类蜜桃刺激视频在线观看| 亚洲不卡一区av| 久久久免费精品少妇| 日韩不卡高清视频| 88在线观看91蜜桃国自产| 亚洲精品一区二区三区丝袜| 国产三级三级三级三级av精品| 91中文字幕制服诱惑| 人人妻人人爱碰千| 国产三级三级三级三级av精品| 成人av激情网一区二区三区| 日韩色在线视频观看免费| 香蕉久久a v一区二区三区| 91国产手机视频在线观看| 五月爱婷婷六月丁香性| 欧美一区二区三区aa大片| 天天在线天天综合网色| 天天做天天舔天天射| 明天我们好好过高清免费| 黑人粗大精品一区二区| 欧美日韩久久久久久精品| 国产成人一区二区三区在线视频| 91精品乱码久久久久久| 青青青手机版视频在线看| 久久久久久添逼视频| 久久久久久精品国产成人| 亚洲欧美日韩一区二区三区不卡| 精品99国内中文字幕| 国产99久久久国产精品成人免费| 国产欧美日韩一区二区三区''| 青青草青青操在线播放| 国产亚洲天堂sss| 亚洲熟妇av熟妇在线| 久久97久久免费视频| 67914熟女在线观看| 乱女乱妇熟女熟妇综合站| 日韩欧美久久免费观看| 初撮日本五十路人妻| 人妻中出视频一区二区| 欧美一区二区三区视频午夜| 青青草成人免费电影| 色综合久久久久久久久| 国产黄色主播网址大全在线播放| 在线观看色有小视频| 精品成人1区2区3区在线看片| 亚洲日本精彩视频在线观看| 厕所偷拍视频一区二区三区| 高清视频在线观看一区二区三区| 91综合精品国产丝袜长腿| 天天在线天天综合网色| av色香蕉一区二区三区| 在线免费av大香蕉| 国产精品网址在线观看| 国语黄色淫秽录像带| 在线观看色有小视频| 国产精品网址在线观看| 麻豆精品123在线观看| 制服巨乳人妻在线| 亚洲一线产区二线产区区| 日韩中文字幕视频在线播放| 最新偷窥偷拍免费视频观看| 麻豆在线视频看片免费| 成人黄色国产网站在线观看| 1024欧美一区二区看片| av传媒高清影院免费| 精品人妻一区二区三区人妻视频 | ass日本丰满熟妇pics| av激情网站在线观看| 亚洲天堂性色综合| 91成人国产精品视频| 97人人人欧美人人妻人人| 先锋资源站中文字幕| 国产精品一区二区三区三级| 国产欧美日韩精品专区黑人| 成人黄视频在线播放| 久久亚洲精品无码系列客服 | 日韩福利视频在线看| 日本av熟女人妻| 五月爱婷婷六月丁香性| 日韩亚洲丝袜系列| 激情四射五月开心六月婷婷| 精品久久久久久亚洲国产999| 欧美中文字幕久久久| 丝袜日韩中文字幕| 久久视频在线免费播放| 久久视频这里都是精品| 久久久久久添逼视频| 亚洲.欧美.日韩.| 日本熟妇乱子伦a片在线观看| 日韩手机在线一区二区三区| 亚洲乳大丰满中文字幕少妇av| 久久久精品99国产国产精| 亚洲日本韩国欧美一起| 国产成人精品久久综合| 久久久亚洲在线视频| 国产一区二中文字幕在线免费观看 | 天天做天天舔天天射| 91在线精品一区二区网站| 国产精品网址在线观看| 四虎网站免费av| 日韩有码视频在线免费观看| 天天日天天干天天色| 日韩欧美xxxx大片| 精品国产麻豆免费成人网| 91一区二区三区精华液| 久久精品人人看人人爽| 精品一区二区三区四区日产| 91久久久久久久久久粉嫩| 亚洲欧洲黄色图区| 清纯唯美激情五月| 久久亚洲熟妇中文字幕| 91一区二区三区精华液| 99.com精品视频| 热久久免费频精品18| 初撮日本五十路人妻| 色亚洲天堂色派对欧美色| 色婷婷国产熟妇人妻露脸| 精品久久久久久999| 日韩亚洲图色在线| 日韩av中文网址| 久久久久久久免费女人体| 99九九99九九热视频| 国产欧美日韩一区二区三区''| 久久精品国产亚洲av不卡性色| 超碰在线免费成人午夜剧场97 | 国产精品99久久电影| 中文字幕久久91| 婷婷中文字幕色婷婷| 国产精品一二三四在线| 91久久婷婷国产麻豆精品| 欧美激情 另类视频 亚洲| 免费看久久久久久久性大片| 中文字幕的不卡人妻| 日韩美女主播人体视频自拍首页| 欧美不卡高清一区二区三区| 日韩成人免费电影三区| 五月天丁香婷婷国产| 国产精品一区二区久久精品蜜臀| 亚洲狠狠婷婷综合久久a| 午夜在线看1000集| 色婷婷久久久swag精品| 久久久成人在线免费视频| 1024欧美一区二区看片| 亚洲精品图片第十八页| 精品人妻二区中文字幕| 人妻中出视频一区二区| 天天操天天干天天做天天射| 麻豆在线视频看片免费| 99精品视频69v精品视频| 五月天色婷婷av在线| 大尺度av一区二区三区| 国产精品久久久久成人片| 精品美女1区2区3区| 国产精品综合手机在线| 亚洲情色av网站| 伊人久久中文字幕综合观看| 91天仙tv国产福利精品| 精品人妻一区二区三区√| 久久视频这里都是精品| 91国偷自产一区二区三区偷拍| 天天操,天天干,天天| 久久视频精彩在线观看| 久久精品中文字幕av| 99久久老熟妇仑乱一区| 日韩av午夜精品| 久久99久久com| 99热在线精品免费观看| 少妇人妻成人在线| 欧美日韩国产综合aⅴ| 欧美激情欧美情色成人在线| 视频一区视频二区三区| 99久久999久久久精品综合| 在线国产小视频麻豆| 美女18禁久久久久麻豆| 日韩亚洲丝袜系列| 中文字幕亚洲专区欧美| 五月综合缴情婷婷六月| 亚洲av激情小说| 四虎网站免费av| 日韩卡一卡二卡三卡四卡五| 亚洲综合成人久久av| 亚洲熟妇av熟妇在线| 蜜桃一区二区三区大香蕉| 激情四射五月开心六月婷婷| 婷婷基地中文字幕| 视频一区视频二区三区| 天天射天天舔天天射| 五月婷婷久久久久久久久| 日韩a大片在线观看| 少妇人妻一区2区中文字幕| 日韩av一区中文| 日韩色在线视频观看免费| 国产乱人妻精品久久久| 欧美日韩国产色图视频| 一区二区三区精品乱子伦……| 伊人久久中文字幕综合观看| 篠田优中文字幕在线播| 久久伊人亚洲综合网| 久久人妻久久人妻一区| 亚洲一区二区三二区厕所偷拍| 久久精品国产久精果冻传媒 | 风间由美交换夫中文字幕| 天天操天天干天天妻| 精品一区二区三区四区人妻69 | 久久一本麻豆天美欧美日韩| 亚洲制服高清中文字幕| 亚洲情色av网站| 人妻中文字幕一二三区| 亚洲一区二区三区久久aa| 日本a级2020在线观看| 成年人在线免费观看黄色片| 玖玖玖玖日在线视频| 最新美女激情av| 无码人妻精品一区二区三区久久 | 久久人人爽爽人人爽av| 午夜寻花美女在线| 99热这里只有的精品| 久久久久中文字幕免费久久久久久 | 久久视频这里都是精品| 日韩成视频在线播放| 99久久窝窝午夜影视| 国产一区二区久久久久久| 91久久婷婷国产麻豆精品| 99精品中文字幕在线视频| 国产欧美日韩亚洲另类第一第二页| 中文字幕熟女人妻在线网页| 先锋资源站中文字幕| 国产成人无码AA精品一区 | 欧美高清在线视频99| 国产一区二区久久久久久 | 精品97人妻无码中文永久| 久久久久久久免费女人体| 加勒比精品一区二区三区| 清纯唯美激情五月| 精品国产久久久久99| 欧美日韩一区二区综合视频| 国产精品首页在线播放| 福利一福利二福利三| 亚洲欧美日韩在线中文字幕小| 亚洲青青青国产观看视频| 亚洲精品蜜桃久久久久| 成人免费av在线网站| 欧美日韩精品欧美日韩| 香蕉在线蕉久在线| 国产欧美一区二区二区精品| 人人妻人人爱碰千| 亚洲伊人网在线观看| 久久久久久久久久久免费网| 国产99成人自拍视频| 免费人妻一区二区三区免费视频 | 国产欧美版日韩综合| 亚洲男人天堂久久| 先锋资源站中文字幕| 久久这里只有精品久| 日韩av中文网址| 日本少妇人妻xxxx| 婷婷亚洲免费基地| 国产日韩一区二区三区啪啪啪| 日韩 美女 在线观看| 国产91色在线i免费| 日韩乱妇乱女熟妇熟女网红| 国产无av码在线观看| 欧美 国产 日韩 一区二区| 国产熟女高潮av77777| 欧美人妻激情中文视频| 日韩三级伦理片免费看| www.亚洲成人色| 青青草久久大香蕉| 91在线观看视频,| 亚洲综合在线伊人| 97久久视频免费在线播放| 天天操天天干天天妻| 日韩成人av影视在线观看| 日韩a视频在线播放视频| 91精品久久久久久五月天| 一区二区三区四区中文字幕| 免费麻豆国产一区二区三区| 熟妇人妻 一区二区三区中文字幕| 伊人久久婷婷av| 韩国女团午夜大尺度福利| 久久久久久添逼视频| 色yeye香蕉凹凸人妻三区| 99re6热在线视频免费观看| 国产欧美一区二区二区精品| 日本加勒比中文字幕久久| 亚洲综合精品久久| 一级久久久久久久18| av福利网站在线观看| 一级片一级片久久精品电影网电影 | 50岁老熟女一区二区三区| 热热久久这里只有精品| 久久久精品国产亚洲av网深田| 日韩精品免费91aa| 精品国产乱码久久久久夜深| 久久午夜福利电影免费试看| 欧美区 日韩区 国产区| 中文字幕一线一区和二区| 久久av一区中文字幕| 精品国产丝袜久久久一区二区| 亚洲人妻中文字幕av首页| 日韩a大片在线观看| 成人av电影免费版| 一区二区三区四区中文字幕| 午夜精品福利小视频| 国产一区二区三区女同| 免费看久久久久久久性大片| 日日夜夜夜视频伊人久久| 88av亚洲精品日韩一区二区| 国产又大又长又粗又硬免费视频 | 精品国产精品视频免费在线观看| 欧美中文字幕视频网| 婷婷 少妇 av| 日本熟妇人妻在线| 天天在线天天综合网色| 久久五月婷婷综合视频| 成人国产一区二区免费| 国产中文字幕在线91| 日韩视频在线播放一区二区| 欧美人妻激情中文视频| 久久久久久人妻无码| 中文字幕人妻互换久久视频| 亚洲天堂网av中文字幕| 天天做天天舔天天射| 丰满大屁股熟妇猛交xxx| 91偷伦一区二区三区蜜臀| 日韩欧美爱爱视频免费观看| 色熟女蜜臀又伦av| 人人狠狠久久综合网| 亚洲欧美日韩一二三四五六七区| 日韩a毛片视频免费看| 少妇惨叫久久久久久久| 大香蕉影视日本大香蕉97| 91在线精品国自产拍| 精品久久精品久久久久| av国偷自产自拍自在线| 日韩草比网站在线免费观看| 日日夜夜夜视频伊人久久| 欧美三级中文字幕久久精品| 97网视频免费在线观看| 欧美人妻一区二区三区在线播放| 日韩 美女 在线观看| 亚洲欧美日韩国产另类专区| 高清视频在线观看一区二区三区| 欧美一区二区性久久久| 日本精品久久久久中人妻| 日韩欧美久久免费观看| 国产又粗又猛又爽又黄的刘涛视 | 国产麻豆一级美女精品| 久久99久久com| 色婷婷久久久swag精品| 日韩日韩av在线| 日韩欧美xxxx大片| 久久综合久久综合久久色| 欧美精品一区二区在线视频| 天天干天天插天天操天天日| 亚洲 欧洲 日韩 人妻| 18禁成年av网站免费看| 国产精品亚洲精品成人| 91影视一区二区三区| 日本少妇人妻xxxx| 性欧美另类sex极品free| 亚洲国产精品成人精品软件| 少妇人妻一区2区中文字幕| 亚洲乱精品中文字字幕| av成人教育在线播放| 日韩男女av在线观看| 日韩av在线专区| 中文字幕亚洲中文字幕| 国产又大又长又粗又硬免费视频 | 亚洲女人中文字幕在线| 亚洲精品久久久久久久久蜜桃| 热热久久这里只有精品| 熟女少妇一区二区精品| 91精品久久久久久久久不卡网站| 青青草久久大香蕉| 亚洲另类色区欧美日韩| 日韩手机在线一区二区三区| 亚洲五月婷婷视频| 狠狠久久综合丁香777米奇| 日韩欧美 国产精品| 欧洲av偷拍亚洲av偷拍| 亚洲:西西一区二区三区四区五区| 综合激情五月天久久| 91中日在线中文字幕| 制服巨乳人妻在线| 少妇人妻视频在线观看| av成人教育在线播放| 2019年中文字幕在线看| 久久久久女优免费视频| 日韩av在线观看免费看看| 91在线观看视频,| 亚洲最大成人网一区二区三区| 日韩精品在线播放第三页| 另类欧美亚洲中文综合| 日韩在线播放视频1区| 国产成人免费精品视频大全| 色综合精品一区二区三区| 中文字幕av最新在线| 激情黄色开心五月天| www.亚洲成人色| 国产精品午夜蜜av| 91精品国产综合久久久久久粉嫩| 亚洲阿v天堂久久| 亚洲欧洲国产一区二区| 亚洲 欧美 制服 人妻| 人人妻人人爱碰千| 91成人国产精品视频| 蜜臀av日韩特黄大片| 99久久久99久久91熟女| av一级二级三级久久久| 日韩有码视频在线免费观看| 国产乱子伦视频免费| 麻豆丝袜美女人妻中文| 日韩毛片亚洲av| 中文字幕人妻互换久久视频| 久久这里只有精品久| 欧美日韩精品欧美日韩| 色熟女蜜臀又伦av| 欧美人妻激情中文视频| 香蕉在线蕉久在线| 中文字幕熟女人妻乳一区二区| 天天操天天干天天做天天射| 日韩在线中文字幕不卡| 五月爱婷婷六月丁香性| 熟女大白屁股在线播放| 污视频在线观看91| 日韩有码在线免费观看视频| 91国产手机视频在线观看| 亚洲综合色激情五月| 亚洲欧美日韩一二三四五六七区| 亚洲男人五月天堂| 欧美区 日韩区 国产区| 精品激情视频在线免费观看| 9久热这里有国产精品| 人妻办公室被强d在线电影| 亚洲av色图com| 欧美一区二区三日韩| 日韩手机在线一区二区三区| 日韩中文字幕有码人妻在线| 在线观看日韩中文| 少妇一区二区在线免费观看| 国产精品一区二区三区三级| 麻豆成人在线免费观看视频| 日韩欧美激情入口| 91精品人妻一区二区三区四区| 欧美日韩精品成人在线| 久久久久999久久日| www.色av成人| 久操免费福利在线视频观看视频| 丰满人妻av白石茉莉奈电影| 又爽又黄的免费视频91| av在线免费在线观看av| 日韩不卡高清视频| 97色视频在线看视频| 伊人久久婷婷av| 久久五月婷婷综合视频| 久久午夜福利电影免费试看| 日本老女人视频在线观看| 亚洲男人五月天堂| 久久人妻少妇嫩草av蜜桃动态图| 国产成人精品久久久久久蜜臀| 久久精品琪琪男人的天堂| 蜜臀av日韩特黄大片| 亚洲成a人片7777| 欧美亚洲av日韩综合一区| 亚洲成人久久久久| 青草青草视频免费2在线观看| 精品人妻二区中文字幕| 午夜无人影视在线| 欧美又色又爽又黄又粗暴| 亚洲另类色区欧美日韩| 欧美自拍 亚洲偷拍| 北条麻妃裤袜一区二区| 蜜臀av日韩特黄大片| 久久久久久久久久性| 久久国产精品久久伊人麻豆| 嫩草一区二区三区四区中文| 最新精品成人在线| 欧美中文字幕久久久| a级黄片在线免费观看| 99久久极品蜜桃臀精品久久| 高清中文字幕乱码在线| 蜜久久久91精品人妻| 精品国产久久久久蜜臀| 亚洲狠狠久久综合一区| 久久99精品久久久久久三级| 91亚洲精品成人在线| 国产三级久久久999111| 中文字幕av久久爽爽| 日韩av在线精品观看| 欧美激情欧美情色成人在线| 亚洲av电影在线一区二区| 久久精品视频在线国国| 婷婷 少妇 av| 在线国产小视频麻豆| 日韩av在线专区| 亚洲情色av网站| 日韩欧美一级在线视频| 中文字幕熟女人妻在线网页| 91在线精品国自产拍| 亚洲欧美日韩在线中文字幕小| 亚洲成人av久久久久| 5858s在线视频| 日韩成视频在线播放| 亚洲 欧洲 日韩 人妻| 久久国产精品人妻酒店| 亚洲视频另类专区| 日本少妇人妻xxxx| 青娱乐国产视频盛| 亚洲激情有码一区二区| 国产精品欧美日韩五月香蕉| 日韩午夜精品啪啪啪| 91综合精品国产丝袜长腿| www.成人国产精品| 老鸭子在线观看免费播放| 四十路av熟女俱乐部| 亚洲男人天堂久久| 在线不卡日韩视频播放| 久草青青草原在线视频| 91一区二区精品在线| 日韩av一区二区三区久久久| 国产精品福利久久久久久久| 欧美一区二区三区成人久久片| 欧美日本韩国乱搞视频| 激情婷婷综合久久五月天| 欧美日韩少妇一二三| 亚洲欧美日韩国产另类专区| 5858s在线视频| 久久免费视频精彩视频| 少妇高潮一区二区三区99欧美| 国产麻豆剧传媒精品视频| 久久亚洲精品日韩高清| 亚洲 欧美 制服 人妻| 精品aa级中文字幕人妻| 五月天色图婷婷亚洲| 五月婷婷蜜臀性色av| 99爱99久久久久久久久久| 午夜在线观看高清完整版| 国产欧美一二三区视频| 中文字幕在线视频亚洲| 亚洲欧美日韩国产另类专区| 久久综合中文字幕一区二区三区| 久久视频这里都是精品| 久久久久999蜜桃视频| 成人黄视频在线播放| 中文字幕一区二区三区中文字幕 | 国产剧情高清在线观看| 亚洲欧洲av在线| 久久人妻久久人妻一区| 亚洲熟妇免费在线视频| 综合 另类 自拍| 国产日韩欧美人妻在线观看| 在线免费av大香蕉| 色婷婷国产熟妇人妻露脸| 亚洲女人中文字幕在线| 麻豆亚州av熟女国产一区二| 亚洲av综合色区手机| 国产精品一二三四在线| 91人妻人人做人碰人人| 综合激情五月天久久| 影音在线精品免费国产资源| 国产成人精品久久久久久蜜臀 | 四虎网站免费av| 欧美日韩在线卡一卡二卡三| 亚洲欧美日韩国产精品综合| 日本熟妇人妻在线| 福利日韩精品中文字幕专区| 色婷婷国产熟妇人妻露脸| 日韩中文字幕在线综合网| 亚洲aⅴ欧美综合一区二区三区 | 亚洲欧美在线视频播放| 亚洲男人天堂久久| 中文字幕亚洲专区欧美| 色综合色综合色综合久久| 97cao瑟瑟在线观看| 亚洲少妇黄色一级片| 18在线观看久久久麻豆| 日日碰狠狠躁久久躁一区二区| 香蕉久久a v一区二区三区| 麻豆成人在线免费观看视频| 亚洲成年人电影天堂| 日韩成人免费电影三区| 亚洲精品图片第十八页| 午夜在线看1000集| www.199麻豆在线视频| 日韩欧美在线视频第一页| 大香蕉大香蕉大香蕉大香蕉大| 日韩在线免费视频精品| 丰满人妻av白石茉莉奈电影| 麻豆网站在线免费看| 蜜臀久久99精品久久久久久久久| 日韩精品综合视频在线| 91精品一二三区在线观看| 亚洲阿v天堂久久| 国产91久久久久久久| 玖玖资源站中文字幕一区二区| 久久久久久精品日韩| 国产剧情高清在线观看| 91中文字幕制服诱惑| 日本女优和黑人的| 午夜精品久久久久久久久二区三区| 日韩在线观看免费全集网站| 99九九99九九热视频| 久久伊人亚洲综合网| 嫩草一区二区三区四区中文| 亚洲欧洲久久精品| 久久行黑国产露脸精品| 91在线精品国自产拍| 久久视频黄色观看网站| 欧美爱情动作片在线一区| 中文字幕人妻互换久久视频| 97国产免费电影网| 中文国产成人精品久久一| 草裙成人精品一区二区三区| 骚妻少妇一区二区| 日韩a大片在线观看| 久久国产精品——国产精品| 精品99国内中文字幕| 99久久999久久久精品综合| 久久久精品99国产国产精| av日韩在线有码a区| 玖玖玖玖日在线视频| 国语黄色淫秽录像带| 麻豆成人在线免费观看视频 | 色哟哟视频在线观看国产| 日韩厕所偷拍美女| 肥臀熟女一区二区三区肥女人| 国产99成人自拍视频| 久久精品 中文字幕| www.亚洲成人色| 中文字幕国产在线观看| 新版天堂av资源在线| 日本精品久久久久中人妻| 国产欧美日韩精品专区黑人 | 国产人妻另类综合专区| av在线免费在线观看av| 北条麻妃裤袜一区二区| 97久久视频免费在线播放| 久久午夜福利电影免费试看| 日韩精品少妇人妻熟女| 大香蕉影视日本大香蕉97| 婷婷亚洲天堂中文字幕| 91porny国产九色| 亚洲不卡一区av| 日韩av在线专区| 日韩福利视频在线看| 中文字幕 日本伊人| 中文字幕成人资源网站| 欧美人妻激情中文视频| 99re热在线精品视频9| 亚洲狠狠久久综合一区| 91超碰熟女在线97| 亚洲精品网站成人久久综合| 又粗又猛又爽黄老大爷视频| 最新美女激情av| 免费麻豆国产一区二区三区| 91国偷自产一区二区三区老熟女| 91国偷自产一区二区三区偷拍| 人人妻人人爱碰千| 篠田优中文字幕在线播| aaaaa亚洲电影| 天美麻豆成人av精品小说| 日本精品久久久久中人妻| 9久热这里有国产精品| 日韩有码在线免费观看视频| 色婷婷精品午夜在线播放| 国产精品欧美日韩五月香蕉| 国产精品久久久久久久久久网站 | 我要看一级国产黄色绿像| 五月婷婷蜜臀性色av| 久久久久久久久人妻精品| 91免费版下载成人| 2019年中文字幕在线看| 国产欧美日韩不卡在线观看| 亚洲精品乱码97久久久久久| 国产成AV人片在线观看天堂无码|