成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

前端:如何處理AJAX請求的重復使用

開發 前端
在開發前端時,我們經常使用AJAX來初始化數據并動態渲染在頁面上,但是在遇到一連串的相同數據都要進行請求時,就有可能對同一個API 發出并發請求,然而,因為這些請求是同時發出,因此響應也非常可能是相同的,這樣講可能不夠清楚,直接寫一個簡易的范例來解釋這個情況。

[[378036]]

 在開發前端時,我們經常使用AJAX來初始化數據并動態渲染在頁面上,但是在遇到一連串的相同數據都要進行請求時,就有可能對同一個API 發出并發請求,然而,因為這些請求是同時發出,因此響應也非常可能是相同的,這樣講可能不夠清楚,直接寫一個簡易的范例來解釋這個情況。

實際范例

首先我們先撰寫一個API:

 

  1. https://localhost:3000/api/v1/users/:uuid 

這個API的回傳值如下:

 

  1.     "name":"Username{uuid}"
  2.     "uuid":"{uuid}" 

隨后開一個Vue的demo,并且先通過Axios寫一個請求的函數:

 

  1. // fetch-user.js 
  2.  
  3. const axios = require('axios'); 
  4.  
  5. module.exports = (uuid) => { 
  6.     let uri = `http://localhost:3000/users/${uuid}`; 
  7.     return new Promise(resolve => { 
  8.         axios.get(uri).then(resolve); 
  9.     }) 
  10. }; 

然后我們在Vue例子中新增一個User Component(User.vue)來負責渲染并請求接口:

  1. <template> 
  2.     <div v-if="init"
  3.         <ul> 
  4.             <li>{{user.name}}</li> 
  5.             <li>{{user.uuid}}</li> 
  6.         </ul> 
  7.     </div> 
  8. </template> 
  9.  
  10. <script> 
  11.     const fetchUser = require('../lib/fetch-user'); 
  12.     export default { 
  13.         name'User'
  14.         data: function() { 
  15.             return { 
  16.                 init: false
  17.                 usernull 
  18.             } 
  19.         }, 
  20.         props: { 
  21.             uuid: String 
  22.         }, 
  23.         async mounted() { 
  24.             const response = await fetchUser(this.uuid); 
  25.             this.init = true
  26.             this.user = response.data; 
  27.         } 
  28.     } 
  29. </script> 

最后將用戶組件放入App.vue中:

  1. <template> 
  2.     <div id="app"
  3.         <user uuid="user-uuid"></user
  4.         <user uuid="user-uuid"></user
  5.         <user uuid="user-uuid"></user
  6.         <user uuid="user-uuid"></user
  7.         <user uuid="user-uuid"></user
  8.         <user uuid="user-uuid"></user
  9.         <user uuid="user-uuid"></user
  10.         <user uuid="user-uuid"></user
  11.         <user uuid="user-uuid"></user
  12.         <user uuid="user-uuid"></user
  13.         <user uuid="user-uuid"></user
  14.         <user uuid="user-uuid"></user
  15.         <user uuid="user-uuid"></user
  16.         <user uuid="user-uuid"></user
  17.         <user uuid="user-uuid"></user
  18.     </div> 
  19. </template> 
  20.  
  21. <script> 
  22. import User from './components/User'
  23.  
  24. export default { 
  25.     name'App'
  26.     components: { 
  27.         User 
  28.     } 
  29. </script> 

接著我們看一下顯示結果:

 

 

 

 

這樣就正確顯示了,然而這里有一個問題非常值得注意:

 

 

 

 

我們打開開發者模式就會發現,每個組件向該API發出了請求,因此就產生了10次的并發請求,但是在這種情況下,實際上我們僅需要讓一個請求出去,另外9個元件等待這個請求的響應然后重新使用即可。

改進的方法

接下來將講解要如何實現關于在同一個組件之間唯一指定API請求一次并分配請求,我們會用到這個元件EventTarget,這個元件有點類似Node.js中的EventEmitter,主要就是用于接收事件。

隨后我們改寫fetchUser()函數:

 

  1. const axios = require('axios'); 
  2.  
  3. /** 
  4.  * 這個 class 是用于存儲 Response Data 的 Event 衍生類 
  5.  */ 
  6. class FetchCompleteEvent extends Event { 
  7.     constructor(type, data) { 
  8.         super(type); 
  9.         this.data = data; 
  10.     } 
  11.  
  12. // 用于請求成功時使用的事件監聽器 
  13. const eventEmitter = new EventTarget(); 
  14.  
  15. // 用于請求失敗時使用的事件監聽器 
  16. const errorEmitter = new EventTarget(); 
  17.  
  18. /** 
  19.  * 用于存儲 URI 以及是否當前正在請求的狀態,如: 
  20.  * http://localhost:8000/users/foo => true 代表已經發出請求,正在等待 Response 
  21.  * http://localhost:8000/users/bar => false 代表當前沒有請求在路上 
  22.  */ 
  23.  
  24. const requestingList = new Map(); 
  25.  
  26. module.exports = (uuid) => { 
  27.  
  28.     let uri = `http://localhost:3000/users/${uuid}`; 
  29.  
  30.     return new Promise((resolve, reject) => { 
  31.  
  32.         // 如果沒有記錄,或者尚未處于請求狀態 
  33.         if (!requestingList.has(uri) || !requestingList.get(uri)) { 
  34.  
  35.             // 進入之后立即將請求狀態設為 true 
  36.             requestingList.set(uri, true); 
  37.  
  38.             // 請求 URI 
  39.             axios.get(uri).then(response => { 
  40.  
  41.                 // 完成請求之后將請求狀態設為 false 
  42.                 requestingList.set(uri, false); 
  43.  
  44.                 // 發出一個事件通知來告訴 callback 請求完成了 
  45.                 eventEmitter.dispatchEvent(new FetchCompleteEvent(uri, response)); 
  46.                 resolve(response); 
  47.  
  48.             }).catch((e) => { 
  49.  
  50.                 // 請求失敗也算是請求完成,將請求狀態設為 false 
  51.                 requestingList.set(uri, false); 
  52.  
  53.                 // 發出一個事件通知來告訴 callback 請求失敗了 
  54.                 errorEmitter.dispatchEvent(new FetchCompleteEvent(uri, e)); 
  55.                 reject(e); 
  56.  
  57.             }) 
  58.         } 
  59.          // 當目前指定的 URL 處于請求狀態,則不做任何事情 
  60.         else { 
  61.  
  62.             // 向成功的事件監聽器注冊,當完成之后 resolve() 
  63.             eventEmitter.addEventListener(uri, (event) => { 
  64.                 resolve(event.data); 
  65.             }); 
  66.  
  67.             // 失敗之后 reject() 
  68.             errorEmitter.addEventListener(uri, (event) => { 
  69.                 reject(event.data); 
  70.             }) 
  71.         } 
  72.     }); 
  73. }; 

接著我們重新運行前端應用程序并查看結果:

 

 

 

 

結果與一開始一模一樣,而是當時我們打開開發者模式就會發現:

 

 

 

 

請求已經被減少到剩下一個了,這是因為所有的元件都重復使用了一個同一個響應。通過這種方法將可以大大減少服務器的負載以及前端的運行時間。

總結

并非每一種情況下都可以使用這種方式來請求資源,如:每次請求資源都一定會發送不一樣的API就不能使用這種方式進行API調用,但是像是上述范例中的用戶資料,電商網站中的商品資料或文章等,類似能夠確保在極短時間之內資源都是相同的API就可以使用這種方式來進行操作。

擴展閱讀

https://dev.to/floatflower/ajax-414j

參考資料

1.https://developer.mozilla.org/zh-TW/docs/Web/API/EventTarget

 

責任編輯:姜華 來源: 前端簡報
相關推薦

2009-07-15 18:07:47

JDBC代碼

2021-06-17 09:32:39

重復請求并發請求Java

2025-01-09 10:20:53

2024-10-16 17:04:13

2023-10-04 07:35:03

2023-09-19 22:41:30

控制器HTTP

2021-01-26 13:40:44

mysql數據庫

2011-09-02 11:06:28

Oracle服務器進程為事務建立回滾段放入dirty lis

2021-01-18 05:13:04

TomcatHttp

2012-08-13 10:23:33

IBMdW

2024-12-19 08:00:00

2019-08-15 10:20:19

云計算技術安全

2020-12-03 07:43:03

JS Ajax JavaScript

2021-03-24 10:40:26

Python垃圾語言

2024-10-23 08:00:00

2023-03-06 08:37:58

JavaNIO

2012-12-12 09:49:41

2020-12-29 09:11:33

LinuxLinux內核

2017-03-13 13:21:34

Git處理大倉庫

2011-12-15 12:32:19

JavaNIO
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本中文字幕在线视频 | 国产一区二区a | 欧美日韩国产欧美 | 日韩免费 | 欧美精品一区二区三区在线 | 情侣酒店偷拍一区二区在线播放 | 亚洲午夜精品视频 | 精品欧美一区二区在线观看视频 | 欧美视频一区二区三区 | 久久中文字幕一区 | 一级免费毛片 | 精久久久 | 日韩在线精品视频 | 蜜桃综合在线 | 男女羞羞视频免费 | 一区二区三区四区不卡视频 | 人人性人人性碰国产 | 久久久久久久久久一区 | 久久久影院 | 日本精品一区二区三区在线观看 | 亚洲欧美国产视频 | 欧美一卡二卡在线观看 | 欧美在线a| 色999视频 | 成人免费网站www网站高清 | 国产精品久久久久久久久图文区 | 国产成人精品一区二区三区在线观看 | 日日天天 | 日韩视频一区二区三区 | 日韩资源| 日韩国产精品一区二区三区 | 国产原创视频 | 亚洲国产精品99久久久久久久久 | 在线亚洲欧美 | 在线免费观看毛片 | 日韩三级一区 | www.一区二区 | 久久三区 | 国产a视频 | 亚洲欧美综合精品久久成人 | 日韩在线视频免费观看 |