Vue如何處理Axios多次請(qǐng)求數(shù)據(jù)顯示問題
Vue處理Axios多次請(qǐng)求數(shù)據(jù)顯示
場(chǎng)景:
一個(gè)搜索框,要求用戶輸入內(nèi)容改變之后立即進(jìn)行搜索
遇到的問題:
用戶頻繁的進(jìn)行搜索詞修改,會(huì)觸發(fā)很多次搜索請(qǐng)求,如果請(qǐng)求有延時(shí),就會(huì)出現(xiàn)顯示不正確的現(xiàn)象
比如下面這個(gè)例子:
- 請(qǐng)求1發(fā)出后,存在延時(shí)大,響應(yīng)1后返回;
- 請(qǐng)求2發(fā)出后,延時(shí)小,響應(yīng)2先返回;
- 最后顯示的內(nèi)容是響應(yīng)1;
而我期待的顯示內(nèi)容,是最后一次的請(qǐng)求結(jié)果響應(yīng)2
請(qǐng)求1 -------> 延時(shí) ---------> 響應(yīng)1
請(qǐng)求2 -> 延時(shí) -> 響應(yīng)2
服務(wù)端代碼
server.py
# -*- coding: utf-8 -*- from flask import Flask, request from flask_cors import CORS import time import random app = Flask(__name__) # 允許跨域 CORS(app, supports_credentials=True) # 路由 @app.route('/search') def search(): # 模擬網(wǎng)絡(luò)延時(shí) sleep = random.random() * 2 time.sleep(sleep) keyword = request.args.get('keyword') return {'keyword': keyword, "sleep": sleep} if __name__ == '__main__': app.run(debug=True)
客戶端代碼
1、直接請(qǐng)求,會(huì)出現(xiàn)數(shù)據(jù)顯示不對(duì)的情況
<template> ? <div class=""> ? ? <input ? ? ? type="text" ? ? ? @input="handleInput" ? ? >{{result}}</div> </template> <script> import axios from 'axios'; export default { ? name: '', ? data() { ? ? return { ? ? ? result: '', ? ? }; ? }, ? methods: { ? ? async handleInput(e) { ? ? ? const keyword = e.target.value; ? ? ? const res = await this.search(keyword); ? ? ? this.result = res.data; ? ? }, ? ? // 直接搜索:可能顯示的不是最后一次搜索結(jié)果 ? ? async search(keyword) { ? ? ? return await axios.get('http://127.0.0.1:5000/search', { ? ? ? ? params: { keyword: keyword }, ? ? ? }); ? ? }, ? }, }; </script> <style lang="scss" scoped> </style>
2、增加一個(gè)定時(shí)器
import axios from 'axios'; export default { ? name: '', ? data() { ? ? return { ? ? ? result: '', ? ? ? timer: null, // 定時(shí)器 ? ? }; ? }, ? methods: { ? ? async handleInput(e) { ? ? ?? ? ? ? const keyword = e.target.value; ? ? ? const res = await this.searchForTimeout(keyword); ? ? ? this.result = res.data; ? ? ?? ? ? }, ? ? // 加定時(shí)器:會(huì)有一個(gè)延遲,如果有超過500ms的網(wǎng)絡(luò)延時(shí),也會(huì)出現(xiàn)數(shù)據(jù)不一致 ? ? async searchForTimeout(keyword) { ? ? ? return new Promise((resolve, reject) => { ? ? ? ? // 清除沒執(zhí)行的timer定時(shí)器 ? ? ? ? clearTimeout(this.timer); ? ? ? ? this.timer = setTimeout(() => { ? ? ? ? ? try { ? ? ? ? ? ? const res = axios.get('http://127.0.0.1:5000/search', { ? ? ? ? ? ? ? params: { keyword: keyword }, ? ? ? ? ? ? }); ? ? ? ? ? ? resolve(res); ? ? ? ? ? } catch (e) { ? ? ? ? ? ? reject(e); ? ? ? ? ? } ? ? ? ? }, 500); ? ? ? }); ? ? }, ? } };
3、加請(qǐng)求時(shí)間戳
import axios from 'axios'; // 使用axios的攔截器 const instance = axios.create(); instance.interceptors.request.use( ? (config) => { ? ? config['X-Timestamp'] = new Date().getTime(); ? ? return config; ? }, ? (err) => { ? ? return Promise.reject(err); ? } ); instance.interceptors.response.use( ? (res) => { ? ? res.data.timestamp = res.config['X-Timestamp']; ? ? return res; ? }, ? (err) => { ? ? return Promise.reject(err); ? } ); export default { ? name: '', ? data() { ? ? return { ? ? ? result: '', ? ? ? timestamp: 0, // 相當(dāng)于版本號(hào) ? ? }; ? }, ? methods: { ? ? async handleInput(e) { ? ? ? const keyword = e.target.value; ? ? ? const res = await this.searchForTimestamp(keyword); ? ? ? // 如果時(shí)間戳大于當(dāng)前記錄的時(shí)間戳則更新數(shù)據(jù) ? ? ? if (res.data.timestamp > this.timestamp) { ? ? ? ? this.timestamp = res.data.timestamp; ? ? ? ? this.result = res.data; ? ? ? } ? ? }, ? ? // 加請(qǐng)求時(shí)間戳:類似樂觀鎖 ? ? async searchForTimestamp(keyword) { ? ? ? return instance.get('http://127.0.0.1:5000/search', { ? ? ? ? params: { keyword: keyword }, ? ? ? }); ? ? }, ? }, };
vue axios多次請(qǐng)求一個(gè)接口取消前面請(qǐng)求
方法一
? ? var CancelToken = axios.CancelToken; ? ? var source = CancelToken.source(); // 每次調(diào)用接口之前都賦值一下 不然不會(huì)觸發(fā)請(qǐng)求 ? ? axios.get('/user/12345', {//get請(qǐng)求在第二個(gè)參數(shù) ? ? ?cancelToken: source.token ? ? }).catch(function(thrown) { ? ? }); ? ? axios.post('/user/12345', {//post請(qǐng)求在第三個(gè)參數(shù) ? ? ?name: 'new name' ? ? }, { ? ? ?cancelToken: source.token ? ? }); ? ? source.cancel('不想請(qǐng)求了');
方法二
const CancelToken = axios.CancelToken; let cancel; ? axios.get('/user/12345', { ? cancelToken: new CancelToken(function executor(c) { ? ? // executor 函數(shù)接收一個(gè) cancel 函數(shù)作為參數(shù) ? ? cancel = c; ? }) }); ? // cancel the request cancel();
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用vuedraggable實(shí)現(xiàn)從左向右拖拽功能
這篇文章主要為大家詳細(xì)介紹了使用vuedraggable實(shí)現(xiàn)從左向右拖拽功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04使用Vue自定義指令實(shí)現(xiàn)Select組件
這篇文章主要介紹了使用Vue自定義指令實(shí)現(xiàn)Select組件,如果哪位朋友對(duì)vue自定義指令不是多了解的話,此篇文章會(huì)對(duì)你有所幫助的,需要的朋友可以參考下2018-05-05ant-design-vue中設(shè)置Table每頁顯示的條目數(shù)量方式
這篇文章主要介紹了ant-design-vue中設(shè)置Table每頁顯示的條目數(shù)量方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10如何優(yōu)雅地在vue中添加權(quán)限控制示例詳解
這篇文章主要給大家介紹了關(guān)于如何優(yōu)雅地在vue中添加權(quán)限控制的相關(guān)資料,文中通過示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03使用vue實(shí)現(xiàn)pdf預(yù)覽功能的方法
許多朋友想要材料上傳之后點(diǎn)擊預(yù)覽實(shí)現(xiàn)在瀏覽器上預(yù)覽的效果,所以本文將給大家介紹如何使用vue實(shí)現(xiàn)pdf預(yù)覽功能,文中有實(shí)現(xiàn)代碼,有需要的朋友可以參考閱讀下2023-08-08vue和webpack打包項(xiàng)目相對(duì)路徑修改的方法
這篇文章主要介紹了vue和webpack打包項(xiàng)目相對(duì)路徑修改的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06Vue組件間的通信pubsub-js實(shí)現(xiàn)步驟解析
這篇文章主要介紹了Vue組件間的通信pubsub-js實(shí)現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03解決vue項(xiàng)目nginx部署到非根目錄下刷新空白的問題
今天小編就為大家分享一篇解決vue項(xiàng)目nginx部署到非根目錄下刷新空白的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09uniapp+vue3實(shí)現(xiàn)上傳圖片組件封裝功能
這篇文章主要介紹了uniapp+vue3實(shí)現(xiàn)上傳圖片組件封裝功能,首先創(chuàng)建一個(gè)?components 文件在里面進(jìn)行組件的創(chuàng)建,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07