在平常開發中,咱們常常會用到ajax與後臺進行數據交互,異步請求的狀況通常分爲兩種,小量數據下的一次性請求與大量數據下的連續或併發請求,這篇文章介紹的就是中斷在大量連續請求的狀況下的做用和必要性。
咱們先設想一個狀況,好比我要畫出一個傳感器最近一個月的監測數據的統計圖,若是我採用一次性獲取全部的數據,若是傳感器的採集週期較短,那麼一個月的時間長度將會有一個很是巨大的的數據量,採用一次獲取的狀況將會使得用戶的等待時間很是漫長,因此咱們就會在知道數據長度的狀況下使用併發請求,在不知道數據長度的狀況下使用連續的請求來獲取數據,而後在本地合併獲取到的數據並繪圖,這樣,用戶只須要等一個請求的時間就能夠看到統計圖了。用戶看到圖後很是滿意,而後點擊了下一個傳感器,程序就會從新執行上面的方法。這個過程看起來很好也沒什麼錯對吧?其實,這樣處理有可能會形成比較嚴重的錯誤,那就是數據污染。javascript
這是咱們整個數據處理的流程圖,有一點須要注意的是從開始發出的三條線是異步的方法,不在主進程中。當第一個請求完成後,第二個或者其餘的請求並無完成。這時用戶點擊了新的傳感器,咱們又會發送一系列的請求到服務器。這時咱們的客戶端就會收到上一個傳感器的數據和新的傳感器的數據。然而系統並不能判斷此次收到的數據是上一輪的仍是這一輪的,都會讓這些數據走正常的方法而後展現出來,這樣,新舊數據就混在了一塊兒。
解決這個問題的思路很簡單,那就是在發行請求前,關閉掉以前發送的全部請求,這樣,新的數據就不會被舊的數據所污染。所幸,咱們使用比較廣的兩種ajax插件都有這樣的方法,下面就以我比較喜歡的axios爲例。java
///假設傳感器的數據有20頁,每頁100條 import axios from 'axios'; let CancelToken = axios.CancelToken; let cancel; function loop(id){///這種請求通常是連續循環的請求 axios.get({ url: '/api/fakePath/', params: { id }, cancelToken: new CancelToken(function executor(c) {///這個函數會傳遞一個取消的函數進來,這裏用cancel來接收 cancel = c; }) }) } /// 使用方法: cancel() let source = CancelToken.source(); function concurrence(arr){///這種是併發多個請求來獲取數據 for(let i in arr){ axios.get({ url: '/api/fakePath/', params: { id:i }, cancelToken: source.token }) } } ///使用方法,這種能夠傳一個message做爲提示: source.cancel('Operation canceled by the user.');
這樣在咱們就建立了一系列的異步請求,而且獲取或者賦予了取消函數。loop函數由於是連續的請求,一次只有一個,因此使用了新建CancelToken,而併發的狀況下,則採用公用一個CancelToken。這樣只要在新請求發起前,調用對應的CancelToken函數,就能夠完美解決數據污染的問題了ios