Vue如何處理Axios多次請求數(shù)據(jù)顯示問題
Vue處理Axios多次請求數(shù)據(jù)顯示
場景:
一個搜索框,要求用戶輸入內(nèi)容改變之后立即進行搜索
遇到的問題:
用戶頻繁的進行搜索詞修改,會觸發(fā)很多次搜索請求,如果請求有延時,就會出現(xiàn)顯示不正確的現(xiàn)象
比如下面這個例子:
- 請求1發(fā)出后,存在延時大,響應(yīng)1后返回;
- 請求2發(fā)出后,延時小,響應(yīng)2先返回;
- 最后顯示的內(nèi)容是響應(yīng)1;
而我期待的顯示內(nèi)容,是最后一次的請求結(jié)果響應(yīng)2
請求1 -------> 延時 ---------> 響應(yīng)1
請求2 -> 延時 -> 響應(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ò)延時 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、直接請求,會出現(xiàn)數(shù)據(jù)顯示不對的情況
<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、增加一個定時器
import axios from 'axios'; export default { ? name: '', ? data() { ? ? return { ? ? ? result: '', ? ? ? timer: null, // 定時器 ? ? }; ? }, ? methods: { ? ? async handleInput(e) { ? ? ?? ? ? ? const keyword = e.target.value; ? ? ? const res = await this.searchForTimeout(keyword); ? ? ? this.result = res.data; ? ? ?? ? ? }, ? ? // 加定時器:會有一個延遲,如果有超過500ms的網(wǎng)絡(luò)延時,也會出現(xiàn)數(shù)據(jù)不一致 ? ? async searchForTimeout(keyword) { ? ? ? return new Promise((resolve, reject) => { ? ? ? ? // 清除沒執(zhí)行的timer定時器 ? ? ? ? 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、加請求時間戳
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)于版本號 ? ? }; ? }, ? methods: { ? ? async handleInput(e) { ? ? ? const keyword = e.target.value; ? ? ? const res = await this.searchForTimestamp(keyword); ? ? ? // 如果時間戳大于當(dāng)前記錄的時間戳則更新數(shù)據(jù) ? ? ? if (res.data.timestamp > this.timestamp) { ? ? ? ? this.timestamp = res.data.timestamp; ? ? ? ? this.result = res.data; ? ? ? } ? ? }, ? ? // 加請求時間戳:類似樂觀鎖 ? ? async searchForTimestamp(keyword) { ? ? ? return instance.get('http://127.0.0.1:5000/search', { ? ? ? ? params: { keyword: keyword }, ? ? ? }); ? ? }, ? }, };
vue axios多次請求一個接口取消前面請求
方法一
? ? var CancelToken = axios.CancelToken; ? ? var source = CancelToken.source(); // 每次調(diào)用接口之前都賦值一下 不然不會觸發(fā)請求 ? ? axios.get('/user/12345', {//get請求在第二個參數(shù) ? ? ?cancelToken: source.token ? ? }).catch(function(thrown) { ? ? }); ? ? axios.post('/user/12345', {//post請求在第三個參數(shù) ? ? ?name: 'new name' ? ? }, { ? ? ?cancelToken: source.token ? ? }); ? ? source.cancel('不想請求了');
方法二
const CancelToken = axios.CancelToken; let cancel; ? axios.get('/user/12345', { ? cancelToken: new CancelToken(function executor(c) { ? ? // executor 函數(shù)接收一個 cancel 函數(shù)作為參數(shù) ? ? cancel = c; ? }) }); ? // cancel the request cancel();
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用vuedraggable實現(xiàn)從左向右拖拽功能
這篇文章主要為大家詳細(xì)介紹了使用vuedraggable實現(xiàn)從左向右拖拽功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04ant-design-vue中設(shè)置Table每頁顯示的條目數(shù)量方式
這篇文章主要介紹了ant-design-vue中設(shè)置Table每頁顯示的條目數(shù)量方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10如何優(yōu)雅地在vue中添加權(quán)限控制示例詳解
這篇文章主要給大家介紹了關(guān)于如何優(yōu)雅地在vue中添加權(quán)限控制的相關(guān)資料,文中通過示例代碼以及圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03Vue組件間的通信pubsub-js實現(xiàn)步驟解析
這篇文章主要介紹了Vue組件間的通信pubsub-js實現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03