防止重復(fù)發(fā)送 Ajax 請求
要考慮并理解 success, complete, error, timeout 這些事件的區(qū)別,并注冊正確的事件,一旦失誤,功能將不再可用;
不可避免地比普通流程要要多注冊一個(gè) complete 事件;
恢復(fù)狀態(tài)的代碼很容易和不相干的代碼混合在一起;
推薦用主動查詢狀態(tài)的方式(A、B,jQuery 為例)或工具函數(shù)的方式(C、D)來去除重復(fù)操作,并提供一些例子作為參考:
A. 獨(dú)占型提交
只允許同時(shí)存在一次提交操作,并且直到本次提交完成才能進(jìn)行下一次提交。
module.submit = function() {
if (this.promise_.state() === 'pending') {
return
}
return this.promise_ = $.post('/api/save')
}
B. 貪婪型提交
無限制的提交,但是以最后一次操作為準(zhǔn);亦即需要盡快給出最后一次操作的反饋,而前面的操作結(jié)果并不重要。
module.submit = function() {
if (this.promise_.state() === 'pending') {
this.promise_.abort()
}
// todo
}
比如某些應(yīng)用的條目中,有一些進(jìn)行類似「喜歡」或「不喜歡」操作的二態(tài)按鈕。如果按下后不立即給出反饋,用戶的目光焦點(diǎn)就可能在那個(gè)按鈕上停頓許久;如果按下時(shí)即時(shí)切換按鈕的狀態(tài),再在程序上用 abort 來實(shí)現(xiàn)積極的提交,這樣既能提高用戶體驗(yàn),還能降低服務(wù)器壓力,皆大歡喜。
C. 節(jié)制型提交
無論提交如何頻繁,任意兩次有效提交的間隔時(shí)間必定會大于或等于某一時(shí)間間隔;即以一定頻率提交。
module.submit = throttle(150, function() {
// todo
})
如果客戶發(fā)送每隔100毫秒發(fā)送過來10次請求,此模塊將只接收其中6個(gè)(每個(gè)在時(shí)間線上距離為150毫秒)進(jìn)行處理。
這也是解決查詢沖突的一種可選手段,比如以知乎草稿舉例,仔細(xì)觀察可以發(fā)現(xiàn):
編輯器的 blur 事件會立即觸發(fā)保存;
保存按鈕的 click 事件也會立即觸發(fā)保存;
但是存在一種情況會使這兩個(gè)事件在數(shù)毫秒內(nèi)連續(xù)發(fā)生——當(dāng)焦點(diǎn)在編輯器內(nèi)部,并且直接去點(diǎn)擊保存按鈕——這時(shí)用 throttle 來處理是可行的。
另外還有一些事件處理會很頻繁地使用 throttle,如: resize、scroll、mousemove。
D. 懶惰型提交
任意兩次提交的間隔時(shí)間,必須大于一個(gè)指定時(shí)間,才會促成有效提交;即不給休息不干活。
module.submit = debounce(150, function() {
// todo
})
還是以知乎草稿舉例,當(dāng)在編輯器內(nèi)按下 ctrl + s 時(shí),可以手動保存草稿;如果你連按,程序會表示不理解為什么你要連按,只有等你放棄連按,它才會繼續(xù)。
============
更多記憶中的例子
方式 C 和 方式 D 有時(shí)更加通用,比如這些情況:
游戲中你撿到一把威力強(qiáng)大的高速武器,為了防止你的子彈在屏幕上打成一條直線,可以 throttle 來控制頻率;
在彈幕型游戲里,為了防止你把射擊鍵夾住來進(jìn)行無腦游戲,可以用 debounce 來控制頻率;
在編譯任務(wù)里,守護(hù)進(jìn)程監(jiān)視了某一文件夾里所有的文件(如任一文件的改變都可以觸發(fā)重新編譯,一次執(zhí)行就需要2秒),但某種操作能夠瞬間造成大量文件改變(如 git checkout),這時(shí)一個(gè)簡單的 debounce 可以使編譯任務(wù)只執(zhí)行一次。
而方式 C 甚至可以和方式 B 組合使用,比如自動完成組件(Google 首頁的搜索就是):
當(dāng)用戶快速輸入文本時(shí)(特別是打字能手),可以 throttle keypress 事件處理函數(shù),以指定時(shí)間間隔來提取文本域的值,然后立即進(jìn)行新的查詢;
當(dāng)新的查詢需要發(fā)送,但上一個(gè)查詢還沒返回結(jié)果時(shí),可以 abort 未完成的查詢,并立即發(fā)送新查詢;
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
- Javascript發(fā)送AJAX請求實(shí)例代碼
- 詳解JavaScript for循環(huán)中發(fā)送AJAX請求問題
- 防止重復(fù)發(fā)送Ajax請求的解決方案
- js與jQuery終止正在發(fā)送的ajax請求的方法
- jQuery通過Ajax向PHP服務(wù)端發(fā)送請求并返回JSON數(shù)據(jù)
- jsp+ajax發(fā)送GET請求的方法
- ie發(fā)送ajax請求返回上一次結(jié)果的解決方法
- jquery跨域請求示例分享(jquery發(fā)送ajax請求)
- jquery+ajax每秒向后臺發(fā)送請求數(shù)據(jù)然后返回頁面的代碼
- Extjs ajax同步請求時(shí)post方式參數(shù)發(fā)送方式
- AJAX中同時(shí)發(fā)送多個(gè)請求XMLHttpRequest對象處理方法
相關(guān)文章
layui禁用側(cè)邊導(dǎo)航欄點(diǎn)擊事件的解決方法
今天小編就為大家分享一篇layui禁用側(cè)邊導(dǎo)航欄點(diǎn)擊事件的解決方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
下雪了 javascript實(shí)現(xiàn)雪花飛舞
下雪了,這篇文章主要介紹了javascript實(shí)現(xiàn)雪花飛舞,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-04-04
CocosCreator Typescript制作俄羅斯方塊游戲
目前關(guān)于cocos開發(fā)俄羅斯方塊的文章幾乎寥寥無幾,因此本文將主要介紹如何通過CocosCreator Typescript制作簡單的俄羅斯方塊游戲,代碼具有一定價(jià)值,感興趣的同學(xué)可以學(xué)習(xí)一下2021-11-11
PHP實(shí)現(xiàn)基于Redis的MessageQueue隊(duì)列封裝操作示例
這篇文章主要介紹了PHP實(shí)現(xiàn)基于Redis的MessageQueue隊(duì)列封裝操作,結(jié)合實(shí)例形式分析了Redis的PHP消息隊(duì)列封裝與使用相關(guān)操作技巧,需要的朋友可以參考下2019-02-02
基于iframe實(shí)現(xiàn)類似于ajax的頁面無刷新
本方法是基于iframe實(shí)現(xiàn)的,需求是form表單提交帶有文件上傳的input標(biāo)簽,示例如下,感興趣的朋友可以參考下2014-05-05

