色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Promise規(guī)范與原理解析

OSC開源社區(qū) ? 來源:OSC開源社區(qū) ? 2023-12-05 15:49 ? 次閱讀

摘要

Promise 對(duì)象用于清晰的處理異步任務(wù)的完成,返回最終的結(jié)果值,本次分享主要介紹 Promise 的基本屬性以及 Promise 內(nèi)部的基礎(chǔ)實(shí)現(xiàn),能夠幫我們更明確使用場(chǎng)景、更快速定位問題。

Promise 出現(xiàn)的原因

首先我們先來看一段代碼:異步請(qǐng)求的層層嵌套
function fn1(params) {
  const xmlHttp = new XMLHttpRequest();
  xmlHttp.onreadystatechange = function(){
    if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
      const fn1Data = {name: 'fn1'}
      console.log(fn1Data, 'fn1Data');
      // 請(qǐng)求2
      (function fn2() {
        xmlHttp.onreadystatechange = function(){
        if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
          const fn2Data = {name: `${fn1Data.name}-fn2`}
          console.log(fn2Data, 'fn2Data');
          // 請(qǐng)求3
          (function fn2() {
            xmlHttp.onreadystatechange = function(){
            if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
              const fn3Data = {name: `${fn2Data.name}-fn3`}
              console.log(fn3Data, 'fn3Data');
            }
          }
          xmlHttp.open("GET","https://v0.yiketianqi.com/api?unescape=1&version=v61", true);
          xmlHttp.send();
          })()
        }
      }
      xmlHttp.open("GET","https://v0.yiketianqi.com/api?unescape=1&version=v61", true);
      xmlHttp.send();
      })()
    }
  }
  xmlHttp.open("GET","https://v0.yiketianqi.com/api?unescape=1&version=v61", true);
  xmlHttp.send();
}

fn1()

或者我們可以將上面的代碼優(yōu)化為下面這樣

function fn1(params) {
  console.log(`我是fn1,我在函數(shù)${params}中執(zhí)行!!!`);
}
  
function fn2(params) {
  try {
    const xmlHttp = new XMLHttpRequest();
    xmlHttp.onreadystatechange = function(){
      if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
        console.log(`我是fn2,我在函數(shù)${params}中執(zhí)行!!!結(jié)果是:`,params.data);
        fn1('fn2')
      }
    }
    xmlHttp.open("GET","https://v0.yiketianqi.com/api?unescape=1&version=v61", true);
    xmlHttp.send();
  } catch (error) {
    console.error(error);
  }
}
  
function fn3() {
  try {
    const xmlHttp = new XMLHttpRequest();
    xmlHttp.onreadystatechange = function(){
      if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
          console.log('fn3請(qǐng)求已完成');
          fn2('fn3')
      }
    }
    xmlHttp.open("GET","https://v0.yiketianqi.com/api?unescape=1&version=v61", true);
    xmlHttp.send();
    console.log('我是f3函數(shù)呀');
  } catch (error) {
    console.error(error);
  }
}
  
fn3()

由上面的兩種寫法的請(qǐng)求可見,在 promise 之前,為了進(jìn)行多個(gè)異步請(qǐng)求并且依賴上一個(gè)異步請(qǐng)求的結(jié)果時(shí),我們必須進(jìn)行層層嵌套,大多數(shù)情況下,我們又對(duì)異步結(jié)果進(jìn)行數(shù)據(jù)處理,這樣使得我們的代碼非常難看,并且難以維護(hù),這就形成了回調(diào)地獄,由此 Promise 開始出現(xiàn)了。回調(diào)地獄缺點(diǎn)
  • 代碼臃腫

  • 可讀性差

  • 耦合性高

  • 不好進(jìn)行異常處理

Promise 的基本概念

含義

  1. ES6 將其寫進(jìn)了語言標(biāo)準(zhǔn)里統(tǒng)一了用法,是一個(gè)構(gòu)造函數(shù),用來生成 Promise 實(shí)例

  2. 參數(shù)為一個(gè)執(zhí)行器函數(shù) (執(zhí)行器函數(shù)是立即執(zhí)行的), 該函數(shù)有兩個(gè)函數(shù)作為參數(shù),第一個(gè)參數(shù)是成功時(shí)的回調(diào),第二個(gè)參數(shù)是失敗時(shí)的回調(diào)

  3. 函數(shù)的方法有 resolve (可以處理成功和失敗)、reject (只處理失敗)、all 等方法

  4. then、catch、finally 方法為 Promise 實(shí)例上的方法

狀態(tài)

  1. pending --- 等待狀態(tài)

  2. Fulfilled --- 執(zhí)行狀態(tài) (resolve 回調(diào)函數(shù),then)

  3. Rejected --- 拒絕狀態(tài) (reject 回調(diào)函數(shù),catch)

  4. 狀態(tài)一旦改變就不會(huì)再變,狀態(tài)只可能是兩種改變,從 pending->Fulfilled,pending->Rejected

  5. 有兩個(gè)關(guān)鍵的屬性:PromiseState --- 狀態(tài)改變,PromiseResult --- 結(jié)果數(shù)據(jù)改變

const p1 = Promise.resolve(64)
const p2 = Promise.reject('我錯(cuò)了')
const p3 = Promise.then()
const p4 = Promise.catch()

// 狀態(tài)改變PromiseState 結(jié)果改變PromiseResult
console.log(new Promise(()=>{}), 'Promise');  // PromiseState='pending' PromiseResult=undefined
console.log(p1,'p1');  // PromiseState='Fulfilled' PromiseResult=64
console.log(p2,'p2');  // PromiseState="Rejected" PromiseResult='我錯(cuò)了'
console.log(p3, 'p3'); // then為實(shí)例上的方法,報(bào)錯(cuò)
console.log(p4, 'p4');  // catch為實(shí)例上的方法,報(bào)錯(cuò)
a047ff72-9296-11ee-939d-92fbcf53809c.png?特點(diǎn)1.錯(cuò)誤信息清晰定位:可以在外層捕獲異常信息(網(wǎng)絡(luò)錯(cuò)誤、語法錯(cuò)誤都可以捕獲),有 “冒泡” 性質(zhì),會(huì)一直向后傳遞,直到被捕獲,所以在最后寫一個(gè) catch 就可以了2.鏈?zhǔn)秸{(diào)用:每一個(gè) then 和 catch 都會(huì)返回一個(gè)新的 Promise,把結(jié)果傳遞到下一個(gè) then/catch 中,因此可以進(jìn)行鏈?zhǔn)秸{(diào)用 --- 代碼簡(jiǎn)潔清晰

結(jié)果由什么決定

resolve

  1. 如果傳遞的參數(shù)是非 Promise 類型的對(duì)象,則返回的結(jié)果是成功狀態(tài)的 Promise 對(duì)象,進(jìn)入下一個(gè) then 里面

  2. 如果傳遞的參數(shù)是 Promise 類型的對(duì)象,則返回的結(jié)果由返回的 Promise 決定,如果返回的是 resolve 則是成功的狀態(tài),進(jìn)入下一個(gè) then 里,如果返回的是 reject 則是失敗的狀態(tài),進(jìn)入下一個(gè) catch 里

reject

  1. 如果傳遞的參數(shù)是非 Promise 類型的對(duì)象,則返回的結(jié)果是拒絕狀態(tài)的 Promise 對(duì)象,進(jìn)入下一個(gè) catch 里面或者是下一個(gè) then 的第二個(gè)參數(shù) reject 回調(diào)里面

  2. 如果傳遞的參數(shù)是 Promise 類型的對(duì)象,則返回的結(jié)果由返回的 Promise 決定,如果返回的是 resolve 則是成功的狀態(tài),進(jìn)入下一個(gè) then 里,如果返回的是 reject 則是拒絕的狀態(tài),進(jìn)入下一個(gè) catch 里面或者是下一個(gè) then 的第二個(gè)參數(shù) reject 回調(diào)里面

這在我們自己封裝的 API 里面也有體現(xiàn):為什么 code 為 1 時(shí)都是 then 接收,其他都是 catch 接收,就是因?yàn)樵?then 里面也就是 resolve 函數(shù)中對(duì) code 碼進(jìn)行了判斷,如果是 1 則返回 Promise.resolve (),進(jìn)入 then 里處理,如果是非 1 則返回 Promise.reject (),進(jìn)入 catch 里處理。

流程圖

a064244a-9296-11ee-939d-92fbcf53809c.png?簡(jiǎn)單使用
// 模擬一個(gè)promise的get請(qǐng)求
let count = 0
function customGet(url){
    count += 1
    return new Promise((resolve, reject)=>{
        const xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET",url, true);
        xmlHttp.onload = ()=>{
          console.log(xmlHttp, 'xmlHttp---onload');
          if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
            console.log('customGet請(qǐng)求成功了');
            // 返回非Promise,結(jié)果為成功狀態(tài)
            resolve({data:`第${count}次請(qǐng)求獲取數(shù)據(jù)成功`})

            // 返回Promise,結(jié)果由Promise決定
            // resolve(Promise.reject('resolve中返回reject'))
          } else {
            reject('customGet請(qǐng)求錯(cuò)誤了')
          }
        }

        // Promise狀態(tài)改變就不會(huì)再變
        // onreadystatechange方法會(huì)被執(zhí)行四次
        // 當(dāng)?shù)卮芜M(jìn)來的時(shí)候,readyState不等于4,執(zhí)行else邏輯,執(zhí)行reject,狀態(tài)變?yōu)镽ejected,所以即使再執(zhí)行if,狀態(tài)之后不會(huì)再改變
        // xmlHttp.onreadystatechange = function(){
        //   console.log(xmlHttp,'xmlHttp---onreadystatechange')
        //   if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
        //     console.log('customGet請(qǐng)求成功了');
        //     resolve({data:`第${count}次請(qǐng)求獲取數(shù)據(jù)成功`})
        //   } else {
        //     reject('customGet請(qǐng)求錯(cuò)誤了')
        //   }
        // }
        xmlHttp.send();
      })
 }

// 使用Promise,并且進(jìn)行鏈?zhǔn)秸{(diào)用
customGet('https://v0.yiketianqi.com/api/cityall?appid=&appsecret=').then((res)=>{
   console.log(res.data);
   return '第一次請(qǐng)求處理后的數(shù)據(jù)'
}).then((data)=>{
   console.log(data)
   // console.log(data.toFixed());
   return customGet('https://v0.yiketianqi.com/api/cityall?appid=&appsecret=')
}).then((res)=>{
   console.log(res.data);
}).catch((err)=>{
    // 以類似'冒泡'的性質(zhì)再外層捕獲所有的錯(cuò)誤
   console.error(err, '這是catch里的錯(cuò)誤信息');
})

手寫實(shí)現(xiàn)簡(jiǎn)單的 Promise通過上面的回顧,我們已經(jīng)了解了 Promise 的關(guān)鍵屬性和特點(diǎn),下面我們一起來實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 Promise 吧
  // 1、封裝一個(gè)Promise構(gòu)造函數(shù),有一個(gè)函數(shù)參數(shù)
  function Promise(executor){
    // 7、添加對(duì)象屬性PromiseState PromiseResult
    this.PromiseState = 'pending'
    this.PromiseResult = null

    // 14、創(chuàng)建一個(gè)保存成功失敗回調(diào)函數(shù)的屬性
    this.callback = null

    // 8、this指向問題
    const that = this

    // 4、executor有兩個(gè)函數(shù)參數(shù)(resolve,reject)
    function resolve(data){
      // 10、Promise狀態(tài)只能修改一次(同時(shí)記得處理reject中的狀態(tài))
      if(that.PromiseState !== 'pending') return

      // console.log(this, 'this');
      // 5、修改對(duì)象的狀態(tài)PromiseState
      that.PromiseState = 'Fulfilled'

      // 6、修改對(duì)象的結(jié)果PromiseResult
      that.PromiseResult = data

      // 15、異步執(zhí)行then里的回調(diào)函數(shù)
      if(that.callback?.onResolve){
        that.callback.onResolve(that.PromiseResult)
      }
    }
    function reject(data){
      console.log(that.PromiseState, 'that.PromiseState');
      if(that.PromiseState !== 'pending') return

      // 9、處理失敗函數(shù)狀態(tài)
      that.PromiseState = 'Rejected'
      that.PromiseResult = data
      console.log(that.PromiseResult, 'that.PromiseResult');
      console.log(that.PromiseState, 'that.PromiseState');

      // 16、異步執(zhí)行then里的回調(diào)函數(shù)
      if(that.callback?.onReject){
        that.callback.onReject(that.PromiseResult)
      }
    }
    // 3、執(zhí)行器函數(shù)是同步調(diào)用的,并且有兩個(gè)函數(shù)參數(shù)
    executor(resolve,reject)
  }
  // 2、函數(shù)的實(shí)例上有方法then
  Promise.prototype.then = function(onResolve,onReject){
    // 20、處理onReject沒有的情況
    if(typeof onReject !== 'function'){
      onReject = reason => {
        throw reason
      }
    }
    // 21、處理onResolve沒有的情況
    if(typeof onResolve !== 'function'){
      onResolve = value => value
    }
    // 17、每一個(gè)then方法都返回一個(gè)新的Promise,并且把上一個(gè)then返回的結(jié)果傳遞出去
    return new Promise((nextResolve,nextReject)=>{
      // 11、處理成功或失敗
      if(this.PromiseState === 'Fulfilled'){
        // 12、將結(jié)果傳遞給函數(shù)
        // onResolve(this.PromiseResult)

        // 18、拿到上一次執(zhí)行完后返回的結(jié)果,判斷是不是Promise
        const result = onResolve(this.PromiseResult)
        if(result instanceof Promise){
          result.then((v)=>{
            nextResolve(v)
          },(r)=>{
            nextReject(r)
          })
        } else {
          nextResolve(result)
        }
      }
      // 當(dāng)你一步步寫下來的時(shí)候有沒有懷疑過為什么不用else
       if(this.PromiseState === 'Rejected'){
            // 第12步同時(shí)處理此邏輯
            // onReject(this.PromiseResult)

            // 22、處理catch異常穿透捕獲錯(cuò)誤
            try {
              const result = onReject(this.PromiseResult)
              if(result instanceof Promise){
                result.then((v)=>{
                  nextResolve(v)
                }).catch((r)=>{
                  nextReject(r)
                })
              } else {
                nextReject(result)
              }
            } catch (error) {
              nextReject(this.PromiseResult)
            }
         }
  
      // 13、異步任務(wù)時(shí)處理成功或失敗,想辦法等異步任務(wù)執(zhí)行完成后才去執(zhí)行這兩個(gè)函數(shù)
      if(this.PromiseState === 'pending'){
        this.callback = {
          onResolve,
          onReject
        }
        console.log(this.callback, 'this.callback');
      }
    })
  }
  // 19、函數(shù)實(shí)例上有方法catch
  Promise.prototype.catch = function(onReject) {
    return this.then(null,onReject)
  }

  // 使用自定義封裝的Promise
  const customP = new Promise((resolve,reject)=>{
    // 模擬異步執(zhí)行請(qǐng)求
    // const xmlHttp = new XMLHttpRequest();
    // xmlHttp.open("GET",'https://v0.yiketianqi.com/api/cityall?appid=&appsecret=', true);
    // xmlHttp.onload = ()=>{
    //   if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
    //     resolve('success')
    //   } else {
    //     reject('error')
    //   }
    // }
    // xmlHttp.send();

    // 同步執(zhí)行
    resolve('success')
    // reject('error')
  })

  console.log(customP, 'customP');
  customP.then((res)=>{
    console.log(res, 'resolve回調(diào)');
    return '第一次回調(diào)'
    // return new Promise((resolve,reject)=>{
    //   reject('錯(cuò)錯(cuò)錯(cuò)')
    // })
  },(err)=>{
    console.error(err, 'reject回調(diào)');
    return '2121'
  }).then(()=>{
    console.log('then里面輸出');
  }).then().catch((err)=>{
    console.error(err, 'catch里的錯(cuò)誤');
  })

針對(duì) resolve 中返回 Promise 對(duì)象時(shí)的內(nèi)部執(zhí)行順序a076ff7a-9296-11ee-939d-92fbcf53809c.png??總結(jié)以上就是我們常用的 Promise 基礎(chǔ)實(shí)現(xiàn),在實(shí)現(xiàn)過程中對(duì)比了 Promise 和函數(shù)嵌套處理異步請(qǐng)求的優(yōu)缺點(diǎn),Promise 仍存在缺點(diǎn),但是的確方便很多,同時(shí)更清晰的理解到錯(cuò)誤處理如何進(jìn)行異常穿透的,也能幫助我們更規(guī)范的使用 Promise 以及快速定位問題所在。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 耦合
    +關(guān)注

    關(guān)注

    13

    文章

    583

    瀏覽量

    100934
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4818

    瀏覽量

    68874
  • 執(zhí)行器
    +關(guān)注

    關(guān)注

    5

    文章

    378

    瀏覽量

    19390

原文標(biāo)題:Promise規(guī)范與原理解析

文章出處:【微信號(hào):OSC開源社區(qū),微信公眾號(hào):OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    鴻蒙原生應(yīng)用開發(fā)-ArkTS語言基礎(chǔ)類庫異步并發(fā)簡(jiǎn)述Promise

    Promise和async/await提供異步并發(fā)能力,是標(biāo)準(zhǔn)的JS異步語法。異步代碼會(huì)被掛起并在之后繼續(xù)執(zhí)行,同一時(shí)間只有一段代碼執(zhí)行,適用于單次I/O任務(wù)的場(chǎng)景開發(fā),例如一次網(wǎng)絡(luò)請(qǐng)求、一次文件
    發(fā)表于 03-07 15:46

    手機(jī)通信原理解析

    `手機(jī)通信原理解析:第 1 章    無線通信原理第2 章    移動(dòng)通信系統(tǒng)第3 章    移動(dòng)通信系統(tǒng)的多址接入技術(shù)第4 章    移動(dòng)通信系統(tǒng)的語音編碼第5 章 GSM移動(dòng)通信系統(tǒng)的數(shù)字
    發(fā)表于 12-14 14:31

    定位技術(shù)原理解析

    【追蹤嫌犯的利器】定位技術(shù)原理解析(4)
    發(fā)表于 05-04 12:20

    Promise對(duì)象的基礎(chǔ)知識(shí)

    Promise 對(duì)象學(xué)習(xí)筆記
    發(fā)表于 06-04 16:19

    如何使用abortController終止fetch和promise

    使用abortController 終止fetch和promise的方法
    發(fā)表于 11-05 08:07

    鋰電池基本原理解析

    【鋰知道】鋰電池基本原理解析:充電及放電機(jī)制電池充電最重要的就是這三步:第一步:判斷電壓
    發(fā)表于 09-15 06:47

    如何更好地理解各種抖動(dòng)技術(shù)規(guī)范

    今天,我將幫助您了解如何更好地理解各種抖動(dòng)技術(shù)規(guī)范。隨著高速應(yīng)用中的定時(shí)要求日趨嚴(yán)格,對(duì)各種抖動(dòng)技術(shù)規(guī)范的更深入理解現(xiàn)已變得非常重要。從 10Gb 以太網(wǎng)網(wǎng)絡(luò)到 PCIe 等高速互聯(lián)技
    發(fā)表于 11-21 06:02

    虛擬存儲(chǔ)器部件原理解析

    虛擬存儲(chǔ)器部件原理解析
    發(fā)表于 04-15 14:25 ?3143次閱讀

    觸摸屏的應(yīng)用與工作原理解析

    觸摸屏的應(yīng)用與工作原理解析
    發(fā)表于 02-08 02:13 ?38次下載

    如何更好的理解抖動(dòng)技術(shù)規(guī)范

    歡迎繼續(xù)關(guān)注《定時(shí)決定一切》系列文章!上次我們探討了對(duì) PLL 環(huán)路濾波器響應(yīng)的理解。今天,我將幫助您了解如何更好地理解各種抖動(dòng)技術(shù)規(guī)范。隨著高速應(yīng)用中的定時(shí)要求日趨嚴(yán)格,對(duì)各種抖動(dòng)技術(shù)規(guī)范
    發(fā)表于 04-08 04:56 ?979次閱讀
    如何更好的<b class='flag-5'>理解</b>抖動(dòng)技術(shù)<b class='flag-5'>規(guī)范</b>?

    關(guān)于Nodejs中最關(guān)鍵也是最難的異步編程做一些介紹和講解

    人們對(duì)于新事物的快速理解一般基于此新事物與生活中某種事物或者規(guī)律的的相似性,但這個(gè)promise并沒有這種特點(diǎn),在我看來,可以去類比promise這個(gè)概念的東西相當(dāng)少,而且類比得相當(dāng)勉強(qiáng),但這也并不意味著
    的頭像 發(fā)表于 04-13 10:17 ?6479次閱讀
    關(guān)于Nodejs中最關(guān)鍵也是最難的異步編程做一些介紹和講解

    CF210SP型調(diào)頻調(diào)幅收音機(jī)電路圖及原理解析

    CF210SP型調(diào)頻調(diào)幅收音機(jī)電路圖及原理解析
    發(fā)表于 01-25 10:46 ?123次下載

    史密斯圓圖和阻抗匹配原理解析

    史密斯圓圖和阻抗匹配原理解析
    的頭像 發(fā)表于 11-02 20:16 ?2031次閱讀

    什么是晶振 晶振工作原理解析

    什么是晶振 晶振工作原理解析
    的頭像 發(fā)表于 12-30 17:13 ?4379次閱讀
    什么是晶振 晶振工作原<b class='flag-5'>理解析</b>

    電磁屏蔽技術(shù)的原理解析

    電磁屏蔽技術(shù)的原理解析 電磁屏蔽技術(shù)是一種利用特定材料或構(gòu)造來阻擋、吸收或反射外界電磁波的技術(shù)。它在電子設(shè)備、通信系統(tǒng)以及電磁環(huán)境的凈化等方面具有重要應(yīng)用,可以有效地防止電磁干擾,保護(hù)設(shè)備和人員
    的頭像 發(fā)表于 03-06 14:58 ?3047次閱讀
    主站蜘蛛池模板: 久久电影精品| 中文字幕在线视频观看| 日本国产成人精品无码区在线网站| 欧美精品v欧洲高清| 色婷婷欧美在线播放内射 | 爱情岛论坛免费在线观看| 国产精品AV色欲蜜臀在线| 美女夫妻内射潮视频| 无颜之月5集全免费看无删除| 18禁无遮挡羞羞污污污污免费| 共妻肉多荤文高h一女n男| 久久久久毛片免费观看| 色翁荡熄月月| 51vv视频社区| 精品粉嫩BBWBBZBBW| 入禽太深免费高清在线观看5| 一本久道久久综合婷婷五月| 囯产精品久久久久久久久免费蜜桃 | 快穿做妓女好爽H| 无码国产欧美日韩精品 | 色欲久久99精品久久久久久AV| 中文中幕无码亚洲在线| 国产在线精品一区二区在线看 | chinese情侣自拍啪hd| 精品久久久久久久高清| 视频一区视频二区ae86| 9亚洲欧洲免费无码在线| 精品国产品在线18年| 性生片30分钟| 国产成在线观看免费视频| 欧美精品一区二区三区四区| 伊在香蕉国产在线视频| 黑兽在线观看高清在线播放樱花| 色www精品视频在线观看| JIZJIZJIZ 日本老师水多| 久久亚洲网站| 永久adc视频年龄确认| 黑人寄宿羽月希产后奶水| 武侠古典久久亚洲精品| 国产高清在线观看| 双性人皇上被c到哭|