JavaScript如何實(shí)現(xiàn)防止重復(fù)的網(wǎng)絡(luò)請(qǐng)求的示例
在開(kāi)發(fā)中,經(jīng)常會(huì)遇到接口重復(fù)請(qǐng)求導(dǎo)致的各種問(wèn)題。對(duì)于重復(fù)的網(wǎng)絡(luò)請(qǐng)求,會(huì)導(dǎo)致頁(yè)面更新多次,發(fā)生頁(yè)面抖動(dòng)的現(xiàn)象,影響用戶體驗(yàn)。例如當(dāng)前頁(yè)面請(qǐng)求還未響應(yīng)完成,就切換到其他路由,那么這些請(qǐng)求直到響應(yīng)返回才會(huì)中止。無(wú)論從用戶體驗(yàn)或者從業(yè)務(wù)嚴(yán)謹(jǐn)方面來(lái)說(shuō),取消無(wú)用的請(qǐng)求確實(shí)是需要避免的。
實(shí)現(xiàn)思路
** 1.在發(fā)送請(qǐng)求前先攔截當(dāng)前請(qǐng)求地址 (url + 方法 + 參數(shù));** 2.開(kāi)啟一個(gè)請(qǐng)求隊(duì)列用于保存 當(dāng)前地址;** 3.每次請(qǐng)求查看請(qǐng)求隊(duì)列里面有沒(méi)有當(dāng)前url地址;** 4.如果請(qǐng)求隊(duì)列里有當(dāng)前url地址就取消當(dāng)前請(qǐng)求,** 5.如果沒(méi)有就發(fā)送請(qǐng)求,當(dāng)請(qǐng)求數(shù)據(jù)返回后,請(qǐng)求隊(duì)列里清除當(dāng)前url地址。
1.平時(shí)我們寫(xiě)接口是這樣的:請(qǐng)求接口文件
import { http } from ’@/plugin/axios’; // 導(dǎo)入請(qǐng)求接口 http// 初始化export function getInit(params) { return http({ method: ’get’, url: ’/xxx/xxx/xx’, params, });}
主要就是這里執(zhí)行 http方法的時(shí)候做操作;執(zhí)行http函數(shù)的時(shí)候能獲取到請(qǐng)求所有配置 config ,返回promise對(duì)象。
2.這里演示使用axios,思路是執(zhí)行請(qǐng)求函數(shù)的時(shí)候外面包一層axios.js配置文件
import axios from ’axios’;import { httpRequest, completeRequest } from ’./options’; // 這里就是我們要實(shí)現(xiàn)的邏輯文件// 里面做一些請(qǐng)求攔截,響應(yīng)攔截操作 具體查看axios文檔const service = axios.create({ baseURL: ’xxx/xxx’,});// 請(qǐng)求攔截器service.interceptors.request.use(config => {}, error => {})// 響應(yīng)攔截器service.interceptors.response.use(response => { completeRequest(response); // 2.響應(yīng)請(qǐng)求回來(lái)執(zhí)行}, error => { })export function http(config) { // => 這里config就是傳遞的請(qǐng)求配置參數(shù) return httpRequest(config, service); // + 1.在這里做一些邏輯操作}3.防止重復(fù)網(wǎng)絡(luò)配置文件
options.js(1)發(fā)送請(qǐng)求前,查看請(qǐng)求隊(duì)列里是否有當(dāng)前請(qǐng)求(url地址來(lái)判斷)
請(qǐng)求隊(duì)列有當(dāng)前url地址, 取消請(qǐng)求 返回promise.reject失敗 沒(méi)有當(dāng)前請(qǐng)求,正常發(fā)送請(qǐng)求;/** * 職責(zé): 防止重復(fù)的網(wǎng)絡(luò)請(qǐng)求 * */let list = new Set(); // 1.請(qǐng)求隊(duì)列// 合并 方法 參數(shù) url地址function getUrl(config = {}) { // get請(qǐng)求 params參數(shù) post請(qǐng)求 data參數(shù), baseURL const { url, method, params, data, baseURL = ’’ } = config; const urlVal = url.replace(baseURL, ’’); return `${urlVal}?${method === ’get’ ? getformatObjVal(params) : getformatObjVal(data)}`;}// 處理 url地址 const getformatObjVal = (obj) => { obj = typeof obj === ’string’ ? JSON.parse(`${obj}`) : obj; var str = []; for (let p in obj) { if (obj.hasOwnProperty(p) && p !== ’_t’) { var item = obj[p] === null ? ’’ : obj[p]; // 處理null str.push(encodeURIComponent(p) + ’=’ + encodeURIComponent(item)); } } return str.join(’&’);}// 2.請(qǐng)求方法export function httpRequest(config = {}, axios) { const url = getUrl(config); //3. 這里我們獲取到了URL地址 if (list.has(url)) { // 4.查看請(qǐng)求隊(duì)列是否有當(dāng)前url地址 return Promise.reject(’In the request’); // 5.在請(qǐng)求隊(duì)列里面 取消當(dāng)前請(qǐng)求, 返回Promise失敗結(jié)果 } // 6. 請(qǐng)求隊(duì)列沒(méi)有當(dāng)前url地址 發(fā)送請(qǐng)求并把url地址存入請(qǐng)求隊(duì)列里 list.add(url); return Promise.resolve(axios); }
(2)請(qǐng)求響應(yīng)回來(lái)后,在請(qǐng)求隊(duì)列里刪除當(dāng)前url地址; (下一次請(qǐng)求就可以正常發(fā)送) options.js
// 請(qǐng)求響應(yīng)回來(lái)執(zhí)行這個(gè)函數(shù)export function completeRequest(response = {}) { const { config } = response; // 1.response里面config能拿到配置參數(shù) const url = getUrl(config); // 2.獲取url地址 if (list.has(url)) { list.delete(url); // 3.刪除請(qǐng)求隊(duì)列中的當(dāng)前請(qǐng)求url地址 }}
axios.js
import axios from ’axios’;import { httpRequest, completeRequest } from ’./options’; // 防止重復(fù)請(qǐng)求const service = axios.create({ baseURL: ’xxx/xxx’,});// 請(qǐng)求攔截器service.interceptors.request.use(config => {}, error => {})// 響應(yīng)攔截器service.interceptors.response.use(response => { completeRequest(response); // 2.響應(yīng)請(qǐng)求回來(lái)執(zhí)行 +}, error => { })// 導(dǎo)出請(qǐng)求export function http(config) { return httpRequest(config, service); // 1.發(fā)送請(qǐng)求前執(zhí)行}
到這里已經(jīng)實(shí)現(xiàn)了防止重復(fù)的網(wǎng)絡(luò)請(qǐng)求,但還有一個(gè)問(wèn)題,響應(yīng)請(qǐng)求發(fā)生異常了要清除請(qǐng)求隊(duì)列中當(dāng)前url地址。不清理,下一次發(fā)送請(qǐng)求直接被取消掉 (這里我就隨便寫(xiě)了一個(gè)方法,把請(qǐng)求隊(duì)列全部清空,大家可以按自己場(chǎng)景來(lái)寫(xiě))。
/** * 清空所有請(qǐng)求隊(duì)列 */export function clearRequestList() { list = new Set(); // 這里我就直接清空了}
完整http.js文件
import axios from ’axios’;import { httpRequest, completeRequest, clearRequestList } from ’./options’; // 防止重復(fù)請(qǐng)求 +const service = axios.create({ baseURL: ’xxx/xxx’,});// 請(qǐng)求攔截器service.interceptors.request.use(config => {}, error => {})// 響應(yīng)攔截器service.interceptors.response.use(response => { completeRequest(response); // 2.響應(yīng)請(qǐng)求回來(lái)執(zhí)行}, error => { clearRequestList(); // + })// 導(dǎo)出請(qǐng)求export function http(config) { return httpRequest(config, service); // 1.發(fā)送請(qǐng)求前執(zhí)行}
完整options.js
/** * 職責(zé): 防止重復(fù)的網(wǎng)絡(luò)請(qǐng)求 * */let list = new Set(); // 1.請(qǐng)求隊(duì)列// 合并 方法 參數(shù) url地址function getUrl(config = {}) { // get請(qǐng)求 params參數(shù) post請(qǐng)求 data參數(shù), baseURL const { url, method, params, baseURL = ’’ } = config; const urlVal = url.replace(baseURL, ’’); return `${urlVal}?${method === ’get’ ? getformatObjVal(params) : ’post’}`;}// 處理 url地址 const getformatObjVal = (obj) => { obj = typeof obj === ’string’ ? JSON.parse(`${obj}`) : obj; var str = []; for (let p in obj) { if (obj.hasOwnProperty(p) && p !== ’_t’) { var item = obj[p] === null ? ’’ : obj[p]; // 處理null str.push(encodeURIComponent(p) + ’=’ + encodeURIComponent(item)); } } return str.join(’&’);}// 2.請(qǐng)求方法export function httpRequest(config = {}, axios) { const url = getUrl(config); //3. 這里我們獲取到了URL地址 if (list.has(url)) { // 4.查看請(qǐng)求隊(duì)列是否有當(dāng)前url地址 return Promise.reject(’In the request’); // 5.在請(qǐng)求隊(duì)列里面 取消當(dāng)前請(qǐng)求, 返回Promise失敗結(jié)果 } // 6. 請(qǐng)求隊(duì)列沒(méi)有當(dāng)前url地址 發(fā)送請(qǐng)求并把url地址存入請(qǐng)求隊(duì)列里 list.add(url); return Promise.resolve(axios);}/** * 請(qǐng)求響應(yīng)回來(lái)執(zhí)行這個(gè)函數(shù) */export function completeRequest(response = {}) { const { config } = response; // 1.response里面config能拿到配置參數(shù) const url = getUrl(config); // 2.獲取url地址 list.has(url) && list.delete(url); // 3.刪除請(qǐng)求隊(duì)列中的當(dāng)前請(qǐng)求url地址}/** * 清空所有請(qǐng)求隊(duì)列 */export function clearRequestList(error) { // error 可以獲取到配置, 做一些操作。 list = new Set(); // 這里我就直接清空了}
以上就是我實(shí)現(xiàn)防止網(wǎng)絡(luò)請(qǐng)求的方式,之前我有使用過(guò)axios中CancelToken來(lái)進(jìn)行取消請(qǐng)求;當(dāng)會(huì)有一些問(wèn)題。
需要配置請(qǐng)求文件,不友好,團(tuán)隊(duì)開(kāi)發(fā)配置也比較麻煩。 需要給每個(gè)請(qǐng)求都配置CancelToken。 有兩個(gè)方法使用它 具體可以參考官網(wǎng)文檔到此這篇關(guān)于JavaScript如何實(shí)現(xiàn)防止重復(fù)的網(wǎng)絡(luò)請(qǐng)求的示例的文章就介紹到這了,更多相關(guān)JavaScript 防止重復(fù)的網(wǎng)絡(luò)請(qǐng)求內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. 編程語(yǔ)言PHP在Web開(kāi)發(fā)領(lǐng)域的優(yōu)勢(shì)在哪?2. 詳解Android studio 動(dòng)態(tài)fragment的用法3. Spring Boot和Thymeleaf整合結(jié)合JPA實(shí)現(xiàn)分頁(yè)效果(實(shí)例代碼)4. 基于android studio的layout的xml文件的創(chuàng)建方式5. Android如何加載Base64編碼格式圖片6. 什么是python的自省7. 圖文詳解vue中proto文件的函數(shù)調(diào)用8. .Net Core使用Coravel實(shí)現(xiàn)任務(wù)調(diào)度的完整步驟9. 在IDEA中實(shí)現(xiàn)同時(shí)運(yùn)行2個(gè)相同的java程序10. 解決Android studio xml界面無(wú)法預(yù)覽問(wèn)題

網(wǎng)公網(wǎng)安備