Take a look at this ⬇️Watch how the data changes
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 >
displaying the correct callback data below
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
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.