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

JavaScript Event Loop 機制詳解與 Vue.js 中實踐應用

開發 開發工具
JavaScript Event Loop 機制詳解與 Vue.js 中實踐應用歸納于筆者的現代 JavaScript 開發:語法基礎與實踐技巧系列文章。本文依次介紹了函數調用棧、MacroTask 與 MicroTask 執行順序、淺析 Vue.js 中 nextTick 實現等內容;本文中引用的參考資料統一聲明在 JavaScript 學習與實踐資料索引。

[[203581]]

JavaScript Event Loop 機制詳解與 Vue.js 中實踐應用歸納于筆者的現代 JavaScript 開發:語法基礎與實踐技巧系列文章。本文依次介紹了函數調用棧、MacroTask 與 MicroTask 執行順序、淺析 Vue.js 中 nextTick 實現等內容;本文中引用的參考資料統一聲明在 JavaScript 學習與實踐資料索引

1. 事件循環機制詳解與實踐應用

JavaScript 是典型的單線程單并發語言,即表示在同一時間片內其只能執行單個任務或者部分代碼片。換言之,我們可以認為某個同域瀏覽器上下中 JavaScript 主線程擁有一個函數調用棧以及一個任務隊列(參考 whatwg 規范);主線程會依次執行代碼,當遇到函數時,會先將函數入棧,函數運行完畢后再將該函數出棧,直到所有代碼執行完畢。

當函數調用棧為空時,運行時即會根據事件循環(Event Loop)機制來從任務隊列中提取出待執行的回調并執行,執行的過程同樣會進行函數幀的入棧出棧操作。每個線程有自己的事件循環,所以每個 Web Worker有自己的,所以它才可以獨立執行。然而,所有同屬一個 origin 的窗體都共享一個事件循環,所以它們可以同步交流。

Event Loop(事件循環)并不是 JavaScript 中獨有的,其廣泛應用于各個領域的異步編程實現中;所謂的 Event Loop 即是一系列回調函數的集合,在執行某個異步函數時,會將其回調壓入隊列中,JavaScript 引擎會在異步代碼執行完畢后開始處理其關聯的回調。

在 Web 開發中,我們常常會需要處理網絡請求等相對較慢的操作,如果將這些操作全部以同步阻塞方式運行無疑會大大降低用戶界面的體驗。

另一方面,我們點擊某些按鈕之后的響應事件可能會導致界面重渲染,如果因為響應事件的執行而阻塞了界面的渲染,同樣會影響整體性能。實際開發中我們會采用異步回調來處理這些操作,這種調用者與響應之間的解耦保證了 JavaScript 能夠在等待異步操作完成之前仍然能夠執行其他的代碼。Event Loop 正是負責執行隊列中的回調并且將其壓入到函數調用棧中,其基本的代碼邏輯如下所示:

  1. while (queue.waitForMessage()) {  
  2. queue.processNextMessage();  

完整的瀏覽器中 JavaScript 事件循環機制圖解如下:

在 Web 瀏覽器中,任何時刻都有可能會有事件被觸發,而僅有那些設置了回調的事件會將其相關的任務壓入到任務隊列中。回調函數被調用時即會在函數調用棧中創建初始幀,而直到整個函數調用棧清空之前任何產生的任務都會被壓入到任務隊列中延后執行;順序的同步函數調用則會創建新的棧幀。總結而言,瀏覽器中的事件循環機制闡述如下:

  • 瀏覽器內核會在其它線程中執行異步操作,當操作完成后,將操作結果以及事先定義的回調函數放入 JavaScript 主線程的任務隊列中。
  • JavaScript 主線程會在執行棧清空后,讀取任務隊列,讀取到任務隊列中的函數后,將該函數入棧,一直運行直到執行棧清空,再次去讀取任務隊列,不斷循環。
  • 當主線程阻塞時,任務隊列仍然是能夠被推入任務的。這也就是為什么當頁面的 JavaScript 進程阻塞時,我們觸發的點擊等事件,會在進程恢復后依次執行。

2. 函數調用棧與任務隊列

在變量作用域與提升一節中我們介紹過所謂執行上下文(Execution Context)的概念,在 JavaScript 代碼執行過程中,我們可能會擁有一個全局上下文,多個函數上下文或者塊上下文;每個函數調用都會創造新的上下文與局部作用域。而這些執行上下文堆疊就形成了所謂的執行上下文棧(Execution Context Stack),便如上文介紹的 JavaScript 是單線程事件循環機制,同時刻僅會執行單個事件,而其他事件都在所謂的執行棧中排隊等待:

而從 JavaScript 內存模型的角度,我們可以將內存劃分為調用棧(Call Stack)、堆(Heap)以及隊列(Queue)等幾個部分:

其中的調用棧會記錄所有的函數調用信息,當我們調用某個函數時,會將其參數與局部變量等壓入棧中;在執行完畢后,會彈出棧首的元素。而堆則存放了大量的非結構化數據,譬如程序分配的變量與對象。隊列則包含了一系列待處理的信息與相關聯的回調函數,每個 JavaScript 運行時都必須包含一個任務隊列。

當調用棧為空時,運行時會從隊列中取出某個消息并且執行其關聯的函數(也就是創建棧幀的過程);運行時會遞歸調用函數并創建調用棧,直到函數調用棧全部清空再從任務隊列中取出消息。換言之,譬如按鈕點擊或者 HTTP 請求響應都會作為消息存放在任務隊列中;需要注意的是,僅當這些事件的回調函數存在時才會被放入任務隊列,否則會被直接忽略。

譬如對于如下的代碼塊:

  1. function fire() { 
  2.     const result = sumSqrt(3, 4) 
  3.     console.log(result); 
  4. function sumSqrt(x, y) { 
  5.     const s1 = square(x) 
  6.     const s2 = square(y) 
  7.     const sum = s1 + s2; 
  8.     return Math.sqrt(sum
  9. function square(x) { 
  10.     return x * x; 
  11.  
  12. fire() 

其對應的函數調用圖(整理自這里)為:

這里還值得一提的是,Promise.then 是異步執行的,而創建 Promise 實例 (executor) 是同步執行的,譬如下述代碼:

  1. (function test() { 
  2.     setTimeout(function() {console.log(4)}, 0); 
  3.     new Promise(function executor(resolve) { 
  4.         console.log(1); 
  5.         for( var i=0 ; i<10000 ; i++ ) { 
  6.             i == 9999 && resolve(); 
  7.         } 
  8.         console.log(2); 
  9.     }).then(function() { 
  10.         console.log(5); 
  11.     }); 
  12.     console.log(3); 
  13. })() 
  14.  
  15. // 輸出結果為: 
  16. // 1 
  17. // 2 
  18. // 3 
  19. // 5 
  20. // 4 

我們可以參考 Promise 規范中有關于 promise.then 的部分:

promise.then(onFulfilled, onRejected)

2.2.4 onFulfilled or onRejected must not be called until the execution context stack contains only platform code. [3.1].

Here “platform code” means engine, environment, and promise implementation code. In practice, this requirement ensures that onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack. This can be implemented with either a “macro-task” mechanism such as setTimeout or setImmediate, or with a “micro-task” mechanism such as MutationObserver or process.nextTick. Since the promise implementation is considered platform code, it may itself contain a task-scheduling queue or “trampoline” in which the handlers are called.

規范要求,onFulfilled 必須在執行上下文棧(Execution Context Stack) 只包含 平臺代碼(platform code) 后才能執行。平臺代碼指引擎,環境,Promise 實現代碼等。實踐上來說,這個要求保證了 onFulfilled 的異步執行(以全新的棧),在 then 被調用的這個事件循環之后。

3. MacroTask(Task) 與 MicroTask(Job)

在面試中我們常常會碰到如下的代碼題,其主要就是考校 JavaScript 不同任務的執行先后順序:

  1. // 測試代碼 
  2. console.log('main1'); 
  3.  
  4. // 該函數僅在 Node.js 環境下可以使用 
  5. process.nextTick(function() { 
  6.     console.log('process.nextTick1'); 
  7. }); 
  8.  
  9. setTimeout(function() { 
  10.     console.log('setTimeout'); 
  11.     process.nextTick(function() { 
  12.         console.log('process.nextTick2'); 
  13.     }); 
  14. }, 0); 
  15.  
  16. new Promise(function(resolve, reject) { 
  17.     console.log('promise'); 
  18.     resolve(); 
  19. }).then(function() { 
  20.     console.log('promise then'); 
  21. }); 
  22.  
  23. console.log('main2'); 
  24.  
  25. // 執行結果 
  26. main1 
  27. promise 
  28. main2 
  29. process.nextTick1 
  30. promise then 
  31. setTimeout 
  32. process.nextTick2 

我們在前文中已經介紹過 JavaScript 的主線程在遇到異步調用時,這些異步調用會立刻返回某個值,從而讓主線程不會在此處阻塞。而真正的異步操作會由瀏覽器執行,主線程則會在清空當前調用棧后,按照先入先出的順序讀取任務隊列里面的任務。

而 JavaScript 中的任務又分為 MacroTask 與 MicroTask 兩種,在 ES2015 中 MacroTask 即指 Task,而 MicroTask 則是指代 Job。典型的 MacroTask 包含了 setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering 等,MicroTask 包含了 process.nextTick, Promises, Object.observe, MutationObserver 等。 二者的關系可以圖示如下:

參考 whatwg 規范 中的描述:一個事件循環(Event Loop)會有一個或多個任務隊列(Task Queue,又稱 Task Source),這里的 Task Queue 就是 MacroTask Queue,而 Event Loop 僅有一個 MicroTask Queue。

每個 Task Queue 都保證自己按照回調入隊的順序依次執行,所以瀏覽器可以從內部到JS/DOM,保證動作按序發生。而在 Task 的執行之間則會清空已有的 MicroTask 隊列,在 MacroTask 或者 MicroTask 中產生的 MicroTask 同樣會被壓入到 MicroTask 隊列中并執行。參考如下代碼:

  1. function foo() { 
  2.   console.log("Start of queue"); 
  3.   bar(); 
  4.   setTimeout(function() { 
  5.     console.log("Middle of queue"); 
  6.   }, 0); 
  7.   Promise.resolve().then(function() { 
  8.     console.log("Promise resolved"); 
  9.     Promise.resolve().then(function() { 
  10.       console.log("Promise resolved again"); 
  11.     }); 
  12.   }); 
  13.   console.log("End of queue"); 
  14.  
  15. function bar() { 
  16.   setTimeout(function() { 
  17.     console.log("Start of next queue"); 
  18.   }, 0); 
  19.   setTimeout(function() { 
  20.     console.log("End of next queue"); 
  21.   }, 0); 
  22.  
  23. foo(); 
  24.  
  25. // 輸出 
  26. Start of queue 
  27. End of queue 
  28. Promise resolved 
  29. Promise resolved again 
  30. Start of next queue 
  31. End of next queue 
  32. Middle of queue 

上述代碼中*** TaskQueue 即為 foo(),foo() 又調用了 bar() 構建了新的 TaskQueue,bar() 調用之后 foo() 又產生了 MicroTask 并被壓入了唯一的 MicroTask 隊列。我們***再總計下 JavaScript MacroTask 與 MicroTask 的執行順序,當執行棧(call stack)為空的時候,開始依次執行:

《這一段在我筆記里也放了好久,無法確定是否拷貝的。。。如果有哪位發現請及時告知。。。(*ฅ́˘ฅ̀*)♡》

  1. 把最早的任務(task A)放入任務隊列
  2. 如果 task A 為null (那任務隊列就是空),直接跳到第6步
  3. 將 currently running task 設置為 task A
  4. 執行 task A (也就是執行回調函數)
  5. 將 currently running task 設置為 null 并移出 task A
  6. 執行 microtask 隊列
  • a: 在 microtask 中選出最早的任務 task X
  • b: 如果 task X 為null (那 microtask 隊列就是空),直接跳到 g
  • c: 將 currently running task 設置為 task X
  • d: 執行 task X
  • e: 將 currently running task 設置為 null 并移出 task X
  • f: 在 microtask 中選出最早的任務 , 跳到 b
  • g: 結束 microtask 隊列

1.跳到***步

4. 淺析 Vue.js 中 nextTick 的實現

在 Vue.js 中,其會異步執行 DOM 更新;當觀察到數據變化時,Vue 將開啟一個隊列,并緩沖在同一事件循環中發生的所有數據改變。如果同一個 watcher 被多次觸發,只會一次推入到隊列中。這種在緩沖時去除重復數據對于避免不必要的計算和 DOM 操作上非常重要。然后,在下一個的事件循環“tick”中,Vue 刷新隊列并執行實際(已去重的)工作。Vue 在內部嘗試對異步隊列使用原生的 Promise.then 和 MutationObserver,如果執行環境不支持,會采用 setTimeout(fn, 0) 代替。

《因為本人失誤,原來此處內容拷貝了 https://www.zhihu.com/question/55364497 這個回答,造成了侵權,深表歉意,已經刪除,后續我會在 github 鏈接上重寫本段》

而當我們希望在數據更新之后執行某些 DOM 操作,就需要使用 nextTick 函數來添加回調:

  1. // HTML 
  2. <div id="example">{{message}}</div> 
  3.  
  4. // JS 
  5. var vm = new Vue({ 
  6.   el: '#example'
  7.   data: { 
  8.     message: '123' 
  9.   } 
  10. }) 
  11. vm.message = 'new message' // 更改數據 
  12. vm.$el.textContent === 'new message' // false 
  13. Vue.nextTick(function () { 
  14.   vm.$el.textContent === 'new message' // true 
  15. }) 

在組件內使用 vm.$nextTick() 實例方法特別方便,因為它不需要全局 Vue ,并且回調函數中的 this 將自動綁定到當前的 Vue 實例上:

  1. Vue.component('example', { 
  2.   template: '<span>{{ message }}</span>'
  3.   data: function () { 
  4.     return { 
  5.       message: '沒有更新' 
  6.     } 
  7.   }, 
  8.   methods: { 
  9.     updateMessage: function () { 
  10.       this.message = '更新完成' 
  11.       console.log(this.$el.textContent) // => '沒有更新' 
  12.       this.$nextTick(function () { 
  13.         console.log(this.$el.textContent) // => '更新完成' 
  14.       }) 
  15.     } 
  16.   } 
  17. }) 

src/core/util/env

  1. /** 
  2.  * 使用 MicroTask 來異步執行批次任務 
  3.  */ 
  4. export const nextTick = (function() { 
  5.   // 需要執行的回調列表 
  6.   const callbacks = []; 
  7.  
  8.   // 是否處于掛起狀態 
  9.   let pending = false
  10.  
  11.   // 時間函數句柄 
  12.   let timerFunc; 
  13.  
  14.   // 執行并且清空所有的回調列表 
  15.   function nextTickHandler() { 
  16.     pending = false
  17.     const copies = callbacks.slice(0); 
  18.     callbacks.length = 0; 
  19.     for (let i = 0; i < copies.length; i++) { 
  20.       copies[i](); 
  21.     } 
  22.   } 
  23.  
  24.   // nextTick 的回調會被加入到 MicroTask 隊列中,這里我們主要通過原生的 Promise 與 MutationObserver 實現 
  25.   /* istanbul ignore if */ 
  26.   if (typeof Promise !== 'undefined' && isNative(Promise)) { 
  27.     let p = Promise.resolve(); 
  28.     let logError = err => { 
  29.       console.error(err); 
  30.     }; 
  31.     timerFunc = () => { 
  32.       p.then(nextTickHandler).catch(logError); 
  33.  
  34.       // 在部分 iOS 系統下的 UIWebViews 中,Promise.then 可能并不會被清空,因此我們需要添加額外操作以觸發 
  35.       if (isIOS) setTimeout(noop); 
  36.     }; 
  37.   } else if ( 
  38.     typeof MutationObserver !== 'undefined' && 
  39.     (isNative(MutationObserver) || 
  40.       // PhantomJS and iOS 7.x 
  41.       MutationObserver.toString() === '[object MutationObserverConstructor]'
  42.   ) { 
  43.     // 當 Promise 不可用時候使用 MutationObserver 
  44.     // e.g. PhantomJS IE11, iOS7, Android 4.4 
  45.     let counter = 1; 
  46.     let observer = new MutationObserver(nextTickHandler); 
  47.     let textNode = document.createTextNode(String(counter)); 
  48.     observer.observe(textNode, { 
  49.       characterData: true 
  50.     }); 
  51.     timerFunc = () => { 
  52.       counter = (counter + 1) % 2; 
  53.       textNode.data = String(counter); 
  54.     }; 
  55.   } else { 
  56.     // 如果都不存在,則回退使用 setTimeout 
  57.     /* istanbul ignore next */ 
  58.     timerFunc = () => { 
  59.       setTimeout(nextTickHandler, 0); 
  60.     }; 
  61.   } 
  62.  
  63.   return function queueNextTick(cb?: Function, ctx?: Object) { 
  64.     let _resolve; 
  65.     callbacks.push(() => { 
  66.       if (cb) { 
  67.         try { 
  68.           cb.call(ctx); 
  69.         } catch (e) { 
  70.           handleError(e, ctx, 'nextTick'); 
  71.         } 
  72.       } else if (_resolve) { 
  73.         _resolve(ctx); 
  74.       } 
  75.     }); 
  76.     if (!pending) { 
  77.       pending = true
  78.       timerFunc(); 
  79.     } 
  80.  
  81.     // 如果沒有傳入回調,則表示以異步方式調用 
  82.     if (!cb && typeof Promise !== 'undefined') { 
  83.       return new Promise((resolve, reject) => { 
  84.         _resolve = resolve; 
  85.       }); 
  86.     } 
  87.   }; 
  88. })(); 

 【本文是51CTO專欄作者“張梓雄 ”的原創文章,如需轉載請通過51CTO與作者聯系】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2017-09-12 09:50:08

JavaScriptEvent LoopVue.js

2019-10-11 09:00:00

JavaScriptEvent Loop前端

2022-06-29 08:37:03

事件循環JS 語言

2017-07-04 17:55:37

Vue.js插件開發

2018-04-04 10:32:13

前端JavascriptVue.js

2024-05-13 08:04:26

Vue.jsWeb應用程序

2023-03-29 14:25:08

Vue.js前端框架

2024-04-08 07:28:27

PiniaVue3狀態管理庫

2023-04-27 08:23:38

JavaScriptVue.jsMVVC

2010-10-09 10:30:03

JS event

2024-04-16 07:46:15

Vue3STOMP協議WebSocket

2013-10-24 15:23:40

Event Loop

2023-04-28 15:20:37

JavaScript事件循環

2022-08-29 18:15:25

Node.js多線程模型

2019-04-01 19:38:28

Vue.jsJavascript前端

2022-04-14 09:35:03

Vue.js設計Reflect

2024-04-07 07:53:12

SpringWeb技術WebSocket

2024-05-17 09:51:11

2022-04-04 16:53:56

Vue.js設計框架

2022-12-01 17:13:44

點贊
收藏

51CTO技術棧公眾號

亚洲欧洲一二三| 国产精品二线| 碰碰在线视频| 26uuu色噜噜精品一区二区| 男人操女人逼免费视频| 免费无码毛片一区二区app| 成人在线视频你懂的| 色婷婷av一区二区三区大白胸 | 国产毛片一区二区三区| 精品国产乱码久久久久久果冻传媒| 国产精品99久久久久久似苏梦涵| 久久久这里只有精品视频| 国产福利短视频| 日本在线一区二区| 天天综合天天综合色| 亚洲精品成人自拍| 亚洲激情第一页| 国产精品沙发午睡系列| av免费在线一区二区三区| 国内精品久久久久影院薰衣草| 九色精品免费永久在线| 日本一区二区三区网站| 亚洲免费黄色网址| 亚洲日本在线观看视频| 自拍偷自拍亚洲精品播放| 国产精品视频免费一区| 中文字幕码精品视频网站| 亚洲国产国产亚洲一二三| 成人av动漫在线| 97人人模人人爽人人喊中文字| 搡老熟女老女人一区二区| 国产精品亚洲欧美一级在线 | 国产精品第108页| 999成人网| 亚洲欧美中文日韩在线| 牲欧美videos精品| 欧美视频一区二区在线观看| 日韩黄色短视频| 米奇精品一区二区三区| 91美女在线观看| 成人综合色站| 欧美女人性生活视频| 国产乱淫片视频| 美女网站久久| 国产做受高潮69| 久久久精品视频在线| 国产大片一区| 中文字幕国产精品久久| 黄色一级片在线观看| 国产毛片精品视频| 国产日韩欧美日韩大片| 波多野结衣高清视频| 怡红院精品视频在线观看极品| 久久久精品久久久久| 亚洲激情视频小说| 日韩av不卡一区| 亚洲国产精久久久久久 | 亚洲国产一区自拍| 少妇熟女视频一区二区三区 | 亚洲黄页视频免费观看| 成人在线视频免费播放| 国内精品偷拍| 亚洲а∨天堂久久精品9966| 色悠悠在线视频| 精品国产乱子伦一区二区| 精品国产一区二区三区四区四 | 国产欧美久久一区二区三区| 国产婷婷成人久久av免费高清 | 热久久视久久精品18亚洲精品| 午夜精品久久久久久久久久久久久蜜桃 | 精品无人码麻豆乱码1区2区| 成人久久精品视频| 性一交一乱一伧老太| 成人一区二区三区视频在线观看| 国产区一区二区| 欧美色视频免费| 国产精品青草久久| 日本三级福利片| 国产高清在线a视频大全| 欧美视频一二三| 在线观看国产中文字幕| 激情综合五月| 亚洲第一男人av| 久久av无码精品人妻系列试探| 成人在线免费视频观看| 九九九久久久久久| 日韩精品手机在线| 免费在线看一区| 亚洲综合最新在线| 偷拍自拍在线| 中文字幕在线不卡国产视频| 人妻激情另类乱人伦人妻| 无码小电影在线观看网站免费| 欧美日韩你懂的| 国产精品果冻传媒| 欧美热在线视频精品999| 在线日韩欧美视频| 久久久精品国产sm调教网站| 久久激情视频| 2019国产精品视频| 欧美中文在线| 亚洲卡通动漫在线| 欧美日韩大尺度| 综合激情久久| 最新国产精品拍自在线播放| 国产乱码久久久久久| 麻豆高清免费国产一区| 国产一区二区在线网站| 男人天堂久久久| 无码av中文一区二区三区桃花岛| 天天色综合天天色| 加勒比色综合久久久久久久久| 永久免费看mv网站入口亚洲| 久久久久亚洲av片无码下载蜜桃| 日韩成人一级大片| 好吊妞www.84com只有这里才有精品| av中文字幕一区二区三区| 亚洲成人一区二区| 在线观看岛国av| 欧美猛男男男激情videos| 欧美精品福利在线| 国产美女明星三级做爰| 国产欧美视频在线观看| 97国产精东麻豆人妻电影 | 亚洲二区在线播放| 日韩和欧美一区二区三区| 国产高清在线精品一区二区三区| 免费网站免费进入在线| 在线影院国内精品| aaaa黄色片| 好看的av在线不卡观看| 国产综合久久久久久| 国产天堂素人系列在线视频| 欧美日韩视频在线| 国产婷婷在线观看| 亚洲xxx拳头交| 国产欧美va欧美va香蕉在线| 精品成人一区二区三区免费视频| 欧美日韩人人澡狠狠躁视频| 影音先锋人妻啪啪av资源网站| 午夜激情一区| 91视频免费在线观看| 成人片在线看| 91麻豆精品国产91久久久资源速度 | 大型av综合网站| 伦伦影院午夜日韩欧美限制| 夜夜嗨av禁果av粉嫩avhd| 国产清纯白嫩初高生在线观看91 | 国产亚洲视频在线观看| 国产中文字幕视频| 久久亚洲精品国产精品紫薇| 能在线观看的av| 亚洲97av| 国产suv精品一区二区三区88区| 午夜国产在线观看| 亚洲中国最大av网站| zjzjzjzjzj亚洲女人| 欧美日韩18| 国产伦精品一区二区三区视频黑人 | 99久久国产精| 精品日韩欧美一区| 国产精品日本精品| 色影院视频在线| 6080午夜不卡| 免费看一级一片| gogo大胆日本视频一区| 国产aaa一级片| 深爱激情综合| 国产区精品视频| 最爽无遮挡行房视频在线| 日韩欧美高清在线| 日本一区二区免费在线观看| 久久久久久久久久电影| 欧美伦理视频在线观看| 久久网站免费观看| 999国内精品视频在线| 超碰激情在线| 亚洲亚裔videos黑人hd| 国产又粗又黄又爽| 亚洲一区二区在线免费观看视频| 国产视频久久久久久| 天堂蜜桃91精品| 一区二区三区免费看| 国产成人夜色高潮福利影视| 国产成人鲁鲁免费视频a| 日本电影在线观看网站| 欧美成人艳星乳罩| 欧美超碰在线观看| 亚洲欧美视频一区| 国内精品久久99人妻无码| 麻豆国产一区二区| 日韩国产一级片| 欧美一区二区三| 99精品国产高清在线观看| 91精品论坛| 久久伊人精品天天| 婷婷五月综合久久中文字幕| 欧美日韩精品一区二区三区 | 欧美涩涩网站| 欧美日韩另类综合| 久久天堂久久| 国产成人一区二区在线| 精品精品导航| 国产一区二区三区在线观看视频| a天堂视频在线| 色88888久久久久久影院野外| 综合一区av| 一区二区三区视频在线| 国产乱码久久久| 精品久久久久久久久中文字幕| av黄色免费在线观看| aaa亚洲精品一二三区| 日韩欧美国产片| 亚洲一区二区三区高清| 久久久久久久久久久久久国产| 美女毛片一区二区三区四区| 91九色蝌蚪成人| 日本黄色成人| 国产精品大片wwwwww| 888av在线视频| 久久视频在线播放| h视频在线免费| 亚洲精品自在久久| 人妻无码中文字幕免费视频蜜桃| 911精品国产一区二区在线| 欧美a视频在线观看| 亚洲丶国产丶欧美一区二区三区| 亚洲欧美精品aaaaaa片| 国产三级精品三级| 精品人妻无码一区二区三区| 不卡影院免费观看| 欧美日韩一区二区区| 激情五月婷婷综合| 日韩一区二区三区不卡视频| 久久久久网站| 国产亚洲天堂网| 免费在线亚洲| 北条麻妃视频在线| 久久久噜噜噜| 激情视频综合网| 日韩精品久久久久久| 黄色片久久久久| 久久综合五月| 人人爽人人av| 日本女人一区二区三区| 爆乳熟妇一区二区三区霸乳| 久久精品123| 成人羞羞国产免费网站| 亚洲成人免费av| 日本裸体美女视频| 亚洲国产精品精华液2区45| 国产人妻人伦精品1国产丝袜| 国产69精品久久久久毛片| 午夜诱惑痒痒网| 国产一区二区在线观看视频| www.五月天色| 国产高清亚洲一区| 97中文字幕在线观看| 粉嫩高潮美女一区二区三区| 国产视频精品视频| 97se亚洲国产综合自在线观| 人妻精品久久久久中文字幕| 久久午夜羞羞影院免费观看| 蜜桃av免费看| 国产精品久久久久婷婷| 粉嫩av性色av蜜臀av网站| 一区二区免费看| 偷偷操不一样的久久| 91久久国产最好的精华液| 亚洲一区在线观| 日韩欧美不卡在线观看视频| 色婷婷激情五月| 亚洲无线码在线一区观看| 美女羞羞视频在线观看| 色综合久久中文字幕综合网小说| 日本色护士高潮视频在线观看 | 不卡视频一区| 精品亚洲自拍| 亚洲啪啪av| 欧美在线亚洲| 黑森林福利视频导航| 精品一区二区三区在线观看| 亚洲免费观看在线| 久久久久综合网| 午夜爽爽爽男女免费观看| 亚洲图片欧美一区| 国产成人无码专区| 欧美一区二区啪啪| 亚洲乱码在线观看| 亚洲精品视频网上网址在线观看| 日本精品一区二区三区在线播放| 欧美疯狂xxxx大交乱88av| 婷婷综合六月| 99久久精品免费看国产四区| 国产一区二区区别| 久久人妻无码一区二区| 久热精品在线| 丰满少妇xbxb毛片日本| 国产精品理伦片| 国产91av视频| 91麻豆精品91久久久久同性| 亚洲三区在线观看无套内射| 日韩在线精品一区| 天堂中文最新版在线中文| 成人免费直播live| 国产精品嫩模av在线| www.九色.com| 久久国产福利国产秒拍| 少妇精品一区二区| 亚洲精品国产高清久久伦理二区| 亚洲欧美自拍视频| 精品国内二区三区| 麻豆系列在线观看| 国产精品wwwwww| 日韩av不卡一区| 丁香六月激情婷婷| 国内不卡的二区三区中文字幕 | 一区二区三区四区亚洲| 天天天天天天天干| 日韩精品欧美激情| 久久99亚洲网美利坚合众国| 成人国产精品一区二区| 欧美码中文字幕在线| 欧美极品欧美精品欧美| 国产成人精品影视| 东方av正在进入| 欧美日韩亚洲高清一区二区| 成人亚洲性情网站www在线观看| 2019av中文字幕| 免费看久久久| 极品粉嫩国产18尤物| 国产成人久久精品77777最新版本| 四虎永久免费地址| 欧美日韩极品在线观看一区| 激情综合闲人网| 国产成人精品一区二区| 综合亚洲色图| 国产日韩一区二区在线| 91美女福利视频| 日韩人妻精品中文字幕| 精品亚洲永久免费精品| 91av亚洲| 日产国产精品精品a∨| 日韩精品一级二级| 午夜在线观看一区| 91国内精品野花午夜精品| 美女毛片在线看| 国产精品第三页| 日韩88av| 午夜一级免费视频| 亚洲青青青在线视频| 国产av无码专区亚洲av| 欧美日本亚洲视频| 欧美黑人做爰爽爽爽| 欧美日韩亚洲一| 久久久精品tv| 中文字幕人妻色偷偷久久| 最近2019中文字幕大全第二页| 色综合一区二区日本韩国亚洲| av电影一区二区三区| 国产一区不卡视频| 精品在线视频免费观看| 亚洲国产成人精品女人久久久| 男人天堂视频在线观看| 欧美人与物videos另类| 麻豆精品一区二区综合av| 老湿机69福利| 精品国产人成亚洲区| 亚洲天堂手机| 亚洲欧美日产图| 国产毛片精品视频| 亚洲天堂一区在线观看| 中文字幕精品久久| 国产精品va视频| www.日本在线播放| 亚洲国产成人在线| 国产激情久久久久久熟女老人av| 97在线观看视频| 欧美一级淫片| 麻豆tv在线观看| 色婷婷精品久久二区二区蜜臀av| 色综合久久久久综合一本到桃花网| 亚洲一区二区三区xxx视频| 99视频一区| 欧美三级视频网站| 精品久久一区二区三区| 精品3atv在线视频| 穿情趣内衣被c到高潮视频| 91免费在线视频观看| 国产熟女一区二区三区五月婷| 久久久久久久爱| 日韩中文字幕高清在线观看| yjizz视频| 欧美日韩黄色影视| 麻豆免费在线| 成年人免费观看的视频| 91麻豆免费视频| 99久久精品国产色欲| 日韩美女福利视频| 欧美日韩在线大尺度|