您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)前端開(kāi)發(fā)中怎么處理AJAX請(qǐng)求的重復(fù)使用的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
在開(kāi)發(fā)前端時(shí),我們經(jīng)常使用AJAX來(lái)初始化數(shù)據(jù)并動(dòng)態(tài)渲染在頁(yè)面上,但是在遇到一連串的相同數(shù)據(jù)都要進(jìn)行請(qǐng)求時(shí),就有可能對(duì)同一個(gè)API 發(fā)出并發(fā)請(qǐng)求,然而,因?yàn)檫@些請(qǐng)求是同時(shí)發(fā)出,因此響應(yīng)也非常可能是相同的,這樣講可能不夠清楚,直接寫(xiě)一個(gè)簡(jiǎn)易的范例來(lái)解釋這個(gè)情況。
實(shí)際范例
首先我們先撰寫(xiě)一個(gè)API:
https://localhost:3000/api/v1/users/:uuid
這個(gè)API的回傳值如下:
{ "name":"Username{uuid}", "uuid":"{uuid}" }
隨后開(kāi)一個(gè)Vue的demo,并且先通過(guò)Axios寫(xiě)一個(gè)請(qǐng)求的函數(shù):
// fetch-user.js const axios = require('axios'); module.exports = (uuid) => { let uri = `http://localhost:3000/users/${uuid}`; return new Promise(resolve => { axios.get(uri).then(resolve); }) };
然后我們?cè)赩ue例子中新增一個(gè)User Component(User.vue)來(lái)負(fù)責(zé)渲染并請(qǐng)求接口:
<template> <div v-if="init"> <ul> <li>{{user.name}}</li> <li>{{user.uuid}}</li> </ul> </div> </template> <script> const fetchUser = require('../lib/fetch-user'); export default { name: 'User', data: function() { return { init: false, user: null } }, props: { uuid: String }, async mounted() { const response = await fetchUser(this.uuid); this.init = true; this.user = response.data; } } </script>
最后將用戶(hù)組件放入App.vue中:
<template> <div id="app"> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> <user uuid="user-uuid"></user> </div> </template> <script> import User from './components/User'; export default { name: 'App', components: { User } } </script>
接著我們看一下顯示結(jié)果:
這樣就正確顯示了,然而這里有一個(gè)問(wèn)題非常值得注意:
我們打開(kāi)開(kāi)發(fā)者模式就會(huì)發(fā)現(xiàn),每個(gè)組件向該API發(fā)出了請(qǐng)求,因此就產(chǎn)生了10次的并發(fā)請(qǐng)求,但是在這種情況下,實(shí)際上我們僅需要讓一個(gè)請(qǐng)求出去,另外9個(gè)元件等待這個(gè)請(qǐng)求的響應(yīng)然后重新使用即可。
改進(jìn)的方法
接下來(lái)將講解要如何實(shí)現(xiàn)關(guān)于在同一個(gè)組件之間唯一指定API請(qǐng)求一次并分配請(qǐng)求,我們會(huì)用到這個(gè)元件EventTarget,這個(gè)元件有點(diǎn)類(lèi)似Node.js中的EventEmitter,主要就是用于接收事件。
隨后我們改寫(xiě)fetchUser()函數(shù):
const axios = require('axios'); /** * 這個(gè) class 是用于存儲(chǔ) Response Data 的 Event 衍生類(lèi) */ class FetchCompleteEvent extends Event { constructor(type, data) { super(type); this.data = data; } } // 用于請(qǐng)求成功時(shí)使用的事件監(jiān)聽(tīng)器 const eventEmitter = new EventTarget(); // 用于請(qǐng)求失敗時(shí)使用的事件監(jiān)聽(tīng)器 const errorEmitter = new EventTarget(); /** * 用于存儲(chǔ) URI 以及是否當(dāng)前正在請(qǐng)求的狀態(tài),如: * http://localhost:8000/users/foo => true 代表已經(jīng)發(fā)出請(qǐng)求,正在等待 Response * http://localhost:8000/users/bar => false 代表當(dāng)前沒(méi)有請(qǐng)求在路上 */ const requestingList = new Map(); module.exports = (uuid) => { let uri = `http://localhost:3000/users/${uuid}`; return new Promise((resolve, reject) => { // 如果沒(méi)有記錄,或者尚未處于請(qǐng)求狀態(tài) if (!requestingList.has(uri) || !requestingList.get(uri)) { // 進(jìn)入之后立即將請(qǐng)求狀態(tài)設(shè)為 true requestingList.set(uri, true); // 請(qǐng)求 URI axios.get(uri).then(response => { // 完成請(qǐng)求之后將請(qǐng)求狀態(tài)設(shè)為 false requestingList.set(uri, false); // 發(fā)出一個(gè)事件通知來(lái)告訴 callback 請(qǐng)求完成了 eventEmitter.dispatchEvent(new FetchCompleteEvent(uri, response)); resolve(response); }).catch((e) => { // 請(qǐng)求失敗也算是請(qǐng)求完成,將請(qǐng)求狀態(tài)設(shè)為 false requestingList.set(uri, false); // 發(fā)出一個(gè)事件通知來(lái)告訴 callback 請(qǐng)求失敗了 errorEmitter.dispatchEvent(new FetchCompleteEvent(uri, e)); reject(e); }) } // 當(dāng)目前指定的 URL 處于請(qǐng)求狀態(tài),則不做任何事情 else { // 向成功的事件監(jiān)聽(tīng)器注冊(cè),當(dāng)完成之后 resolve() eventEmitter.addEventListener(uri, (event) => { resolve(event.data); }); // 失敗之后 reject() errorEmitter.addEventListener(uri, (event) => { reject(event.data); }) } }); };
接著我們重新運(yùn)行前端應(yīng)用程序并查看結(jié)果:
結(jié)果與一開(kāi)始一模一樣,而是當(dāng)時(shí)我們打開(kāi)開(kāi)發(fā)者模式就會(huì)發(fā)現(xiàn):
請(qǐng)求已經(jīng)被減少到剩下一個(gè)了,這是因?yàn)樗械脑贾貜?fù)使用了一個(gè)同一個(gè)響應(yīng)。通過(guò)這種方法將可以大大減少服務(wù)器的負(fù)載以及前端的運(yùn)行時(shí)間。
感謝各位的閱讀!關(guān)于“前端開(kāi)發(fā)中怎么處理AJAX請(qǐng)求的重復(fù)使用”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。