摘要:在日常開發(fā)中,我們經(jīng)常會(huì)用到與后臺(tái)進(jìn)行數(shù)據(jù)交互,異步請(qǐng)求的情況一般分為兩種,小量數(shù)據(jù)下的一次性請(qǐng)求與大量數(shù)據(jù)下的連續(xù)或并發(fā)請(qǐng)求,這篇文章介紹的就是中斷在大量連續(xù)請(qǐng)求的情況下的作用和必要性。當(dāng)?shù)谝粋€(gè)請(qǐng)求完成后,第二個(gè)或者其他的請(qǐng)求并沒有完成。
在日常開發(fā)中,我們經(jīng)常會(huì)用到ajax與后臺(tái)進(jìn)行數(shù)據(jù)交互,異步請(qǐng)求的情況一般分為兩種,小量數(shù)據(jù)下的一次性請(qǐng)求與大量數(shù)據(jù)下的連續(xù)或并發(fā)請(qǐng)求,這篇文章介紹的就是中斷在大量連續(xù)請(qǐng)求的情況下的作用和必要性。
我們先設(shè)想一個(gè)情況,比如我要畫出一個(gè)傳感器最近一個(gè)月的監(jiān)測數(shù)據(jù)的統(tǒng)計(jì)圖,如果我采用一次性獲取所有的數(shù)據(jù),如果傳感器的采集周期較短,那么一個(gè)月的時(shí)間長度將會(huì)有一個(gè)非常巨大的的數(shù)據(jù)量,采用一次獲取的情況將會(huì)使得用戶的等待時(shí)間非常漫長,所以我們就會(huì)在知道數(shù)據(jù)長度的情況下使用并發(fā)請(qǐng)求,在不知道數(shù)據(jù)長度的情況下使用連續(xù)的請(qǐng)求來獲取數(shù)據(jù),然后在本地合并獲取到的數(shù)據(jù)并繪圖,這樣,用戶只需要等一個(gè)請(qǐng)求的時(shí)間就可以看到統(tǒng)計(jì)圖了。用戶看到圖后非常滿意,然后點(diǎn)擊了下一個(gè)傳感器,程序就會(huì)重新執(zhí)行上面的方法。這個(gè)過程看起來很好也沒什么錯(cuò)對(duì)吧?其實(shí),這樣處理有可能會(huì)造成比較嚴(yán)重的錯(cuò)誤,那就是數(shù)據(jù)污染。
這是我們整個(gè)數(shù)據(jù)處理的流程圖,有一點(diǎn)需要注意的是從開始發(fā)出的三條線是異步的方法,不在主進(jìn)程中。當(dāng)?shù)谝粋€(gè)請(qǐng)求完成后,第二個(gè)或者其他的請(qǐng)求并沒有完成。這時(shí)用戶點(diǎn)擊了新的傳感器,我們又會(huì)發(fā)送一系列的請(qǐng)求到服務(wù)器。這時(shí)我們的客戶端就會(huì)收到上一個(gè)傳感器的數(shù)據(jù)和新的傳感器的數(shù)據(jù)。然而系統(tǒng)并不能判斷這次收到的數(shù)據(jù)是上一輪的還是這一輪的,都會(huì)讓這些數(shù)據(jù)走正常的方法然后展示出來,這樣,新舊數(shù)據(jù)就混在了一起。
解決這個(gè)問題的思路很簡單,那就是在發(fā)行請(qǐng)求前,關(guān)閉掉之前發(fā)送的所有請(qǐng)求,這樣,新的數(shù)據(jù)就不會(huì)被舊的數(shù)據(jù)所污染。所幸,我們使用比較廣的兩種ajax插件都有這樣的方法,下面就以我比較喜歡的axios為例。
///假設(shè)傳感器的數(shù)據(jù)有20頁,每頁100條 import axios from "axios"; let CancelToken = axios.CancelToken; let cancel; function loop(id){///這種請(qǐng)求一般是連續(xù)循環(huán)的請(qǐng)求 axios.get({ url: "/api/fakePath/", params: { id }, cancelToken: new CancelToken(function executor(c) {///這個(gè)函數(shù)會(huì)傳遞一個(gè)取消的函數(shù)進(jìn)來,這里用cancel來接收 cancel = c; }) }) } /// 使用方法: cancel() let source = CancelToken.source(); function concurrence(arr){///這種是并發(fā)多個(gè)請(qǐng)求來獲取數(shù)據(jù) for(let i in arr){ axios.get({ url: "/api/fakePath/", params: { id:i }, cancelToken: source.token }) } } ///使用方法,這種可以傳一個(gè)message作為提示: source.cancel("Operation canceled by the user.");
這樣在我們就創(chuàng)建了一系列的異步請(qǐng)求,并且獲取或者賦予了取消函數(shù)。loop函數(shù)因?yàn)槭沁B續(xù)的請(qǐng)求,一次只有一個(gè),所以使用了新建CancelToken,而并發(fā)的情況下,則采用公用一個(gè)CancelToken。這樣只要在新請(qǐng)求發(fā)起前,調(diào)用對(duì)應(yīng)的CancelToken函數(shù),就可以完美解決數(shù)據(jù)污染的問題了
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/96215.html
摘要:事件循環(huán)背景是一門單線程非阻塞的腳本語言,單線程意味著,代碼在執(zhí)行的任何時(shí)候,都只有一個(gè)主線程來處理所有的任務(wù)。在意識(shí)到該問題之際,新特性中的可以讓成為一門多線程語言,但實(shí)際開發(fā)中使用存在著諸多限制。這個(gè)地方被稱為執(zhí)行棧。 事件循環(huán)(Event Loop) 背景 JavaScript是一門單線程非阻塞的腳本語言,單線程意味著,JavaScript代碼在執(zhí)行的任何時(shí)候,都只有一個(gè)主線程來...
摘要:在上面我們已經(jīng)知道瀏覽器是一幀一幀執(zhí)行的,在兩個(gè)執(zhí)行幀之間,主線程通常會(huì)有一小段空閑時(shí)間,可以在這個(gè)空閑期調(diào)用空閑期回調(diào),執(zhí)行一些任務(wù)。另外由于這些堆棧是可以自己控制的,所以可以加入并發(fā)或者錯(cuò)誤邊界等功能。 文章首發(fā)于個(gè)人博客 前言 2016 年都已經(jīng)透露出來的概念,這都 9102 年了,我才開始寫 Fiber 的文章,表示慚愧呀。不過現(xiàn)在好的是關(guān)于 Fiber 的資料已經(jīng)很豐富了,...
摘要:聲明的變量不得改變值,這意味著,一旦聲明變量,就必須立即初始化,不能留到以后賦值。 雖然今年沒有換工作的打算 但為了跟上時(shí)代的腳步 還是忍不住整理了一份最新前端知識(shí)點(diǎn) 知識(shí)點(diǎn)匯總 1.HTML HTML5新特性,語義化瀏覽器的標(biāo)準(zhǔn)模式和怪異模式xhtml和html的區(qū)別使用data-的好處meta標(biāo)簽canvasHTML廢棄的標(biāo)簽IE6 bug,和一些定位寫法css js放置位置和原因...
摘要:聲明的變量不得改變值,這意味著,一旦聲明變量,就必須立即初始化,不能留到以后賦值。 雖然今年沒有換工作的打算 但為了跟上時(shí)代的腳步 還是忍不住整理了一份最新前端知識(shí)點(diǎn) 知識(shí)點(diǎn)匯總 1.HTML HTML5新特性,語義化瀏覽器的標(biāo)準(zhǔn)模式和怪異模式xhtml和html的區(qū)別使用data-的好處meta標(biāo)簽canvasHTML廢棄的標(biāo)簽IE6 bug,和一些定位寫法css js放置位置和原因...
摘要:聲明的變量不得改變值,這意味著,一旦聲明變量,就必須立即初始化,不能留到以后賦值。 雖然今年沒有換工作的打算 但為了跟上時(shí)代的腳步 還是忍不住整理了一份最新前端知識(shí)點(diǎn) 知識(shí)點(diǎn)匯總 1.HTML HTML5新特性,語義化瀏覽器的標(biāo)準(zhǔn)模式和怪異模式xhtml和html的區(qū)別使用data-的好處meta標(biāo)簽canvasHTML廢棄的標(biāo)簽IE6 bug,和一些定位寫法css js放置位置和原因...
閱讀 2355·2021-11-23 09:51
閱讀 2006·2021-10-14 09:43
閱讀 2776·2021-09-27 13:35
閱讀 1157·2021-09-22 15:54
閱讀 2510·2021-09-13 10:36
閱讀 3810·2019-08-30 15:56
閱讀 3412·2019-08-30 14:09
閱讀 1722·2019-08-30 12:57