Take a look at this ⬇️
On this page, we have 3 buttons to fetch 3 different sets of asynchronous callback data. The same container is used to display the data below. When buttons 2 and 3 are quickly clicked, the asynchronous request for button 2 is still pending while the request for button 3 has been sent. Once the callback for button 2 is complete, the data for button 2 is displayed below. After a while, when the callback for button 3 is complete, the data is replaced with the corresponding data for button 3.
Optimization Method 1 Set a flag to indicate which button callback needs to be displayed.
example 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <meta http-equiv ="X-UA-Compatible" content ="IE=edge" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <script src ="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js" > </script > <script src ="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js" > </script > <title > Request Optimization Example</title > <style > .btns button { margin-right : 10px ; } .result { margin-top : 20px ; } </style > </head > <body > <div id ="app" > <div class ="btns" > <button v-for ="index in 3" :key ="index" @click ="getResult(index)" > {{ `获取结果${index}` }} </button > </div > <div class ="result" > <div v-show ="loading" > 加载中</div > <div v-show ="!loading" > {{ result }}</div > </div > </div > <script > var app = new Vue ({ el : "#app" , data : { loading : false , result : "" , activeIndex : null , }, methods : { getResult (index ) { this .loading = true ; this .activeIndex = index; setTimeout (() => { if (index !== this .activeIndex ) { return ; } this .result = `按钮${index} 的异步回调结果` ; this .loading = false ; }, 1000 ); }, }, }); </script > </body > </html >
Although the correct callback results can be displayed at this time, unnecessary asynchronous requests are still being made when the button is clicked.
Optimization Method 2 Cacel request by Axios’s cancelToken
完整代码如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 <!DOCTYPE html > <html lang ="zh-CN" > <head > <meta charset ="UTF-8" /> <meta http-equiv ="X-UA-Compatible" content ="IE=edge" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <script src ="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js" > </script > <script src ="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js" > </script > <title > Request Optimization Example</title > <style > .btns button { margin-right : 10px ; } .result { margin-top : 20px ; } </style > </head > <body > <div id ="app" > <div class ="btns" > <button v-for ="index in 3" :key ="index" @click ="getResult(index)" > {{ `获取结果${index}` }} </button > </div > <div class ="result" > <div v-show ="loading" > 加载中</div > <div v-show ="!loading" > {{ result }}</div > </div > </div > <script > var app = new Vue ({ el : "#app" , data : { loading : false , result : "" , cancelFetch : null , }, methods : { getResult (index ) { this .loading = true ; if (this .cancelFetch ) { this .cancelFetch (); this .cancelFetch = null ; } axios .post ("https://api.vvhan.com/api/bing?type=json" , null , { cancelToken : new axios.CancelToken ((c ) => { this .cancelFetch = c; }), }) .then ((res ) => { this .result = `按钮${index} 的异步回调结果` ; this .loading = false ; }) .catch (() => {}); }, }, }); </script > </body > </html >
Also, we can useDebounce to avoid firing unnecessary callback.
That’s all, hope this helps.