Debounce散罕,又稱防抖動(dòng)函數(shù), 常被被用來控制 前端異步請(qǐng)求及其它高耗任務(wù)的頻率傀蓉。
概念比較抽象欧漱,了解一個(gè)業(yè)務(wù)場景,就很容易理解了僚害。
比如通過搜索過濾一個(gè)列表硫椰,通過“@change=“search”監(jiān)聽輸入向后臺(tái)發(fā)起請(qǐng)求,如果每輸入一個(gè)字母就調(diào)用一次”search“向后臺(tái)發(fā)送一次請(qǐng)求萨蚕,效率將會(huì)很低靶草,如果可以將調(diào)用search函數(shù)控制在一定時(shí)間內(nèi),比如1秒內(nèi)岳遥,在這一秒鐘奕翔,我輸入了5個(gè)字母,search函數(shù)被調(diào)用了5次浩蓉,但是只向后臺(tái)發(fā)送一次請(qǐng)求派继,是不是效率就會(huì)提升很多,不需要頻繁調(diào)接口捻艳。
<el-input placeholder="輸入關(guān)鍵字進(jìn)行查詢"
v-model="searchText"
@keyup.native="search"></el-input>
methods: {
search () {
console.log("此處向后臺(tái)發(fā)起請(qǐng)求")
}
},
而debounce函數(shù)就是解決這個(gè)問題的驾窟,顧名思義,debounce是“去抖動(dòng)”的意思认轨,結(jié)合以上的業(yè)務(wù)場景就很形象绅络,一段時(shí)間內(nèi)輸入值的變化都是“抖動(dòng)”,不是要真正向后臺(tái)發(fā)請(qǐng)求的真正“動(dòng)作”嘁字,為了讓后臺(tái)不被騷擾恩急,我把這些“抖動(dòng)”的小動(dòng)作都屏蔽掉。
然而纪蜒,在學(xué)習(xí)使用debounce函數(shù)的過程中衷恭,我踩了好幾個(gè)坑,分享出來以供借鑒纯续。
我使用的是lodash自帶的debounce函數(shù)随珠,官方文檔這樣描述的
_.debounce(func, [wait=0], [options={}])
兩個(gè)必選參數(shù)中灭袁,第一個(gè)是防抖動(dòng)的函數(shù),第二個(gè)是防抖動(dòng)的時(shí)間毫秒數(shù)窗看。很像“setTimeout”函數(shù)的寫法简卧。
于是我將代碼寫成:
// 錯(cuò)誤示例
methods: {
search () {
this._.debounce(() => {
console.log('此處向后臺(tái)發(fā)起請(qǐng)求:' + this.searchText)
}, 1000)
}
}
控制臺(tái)既沒有報(bào)錯(cuò),也沒有打印出任何東西烤芦,后來經(jīng)同事提醒举娩,發(fā)現(xiàn)debounce函數(shù)的返回值是一個(gè)function,跟setTimeout使用是不一樣的
Returns
(Function): Returns the new debounced function.
于是构罗,我將代碼改為铜涉,在debounce后面加了個(gè)(),讓這個(gè)返回的函數(shù)立即執(zhí)行
// 錯(cuò)誤示例
methods: {
search () {
this._.debounce(() => {
console.log('此處向后臺(tái)發(fā)起請(qǐng)求:' + this.searchText)
}, 1000)()
}
},
這次遂唧,控制臺(tái)終于打出了我想要的結(jié)果芙代,但是。盖彭。纹烹。但是,并沒有起到防抖動(dòng)的作用召边,我在一秒鐘按幾次鍵盤铺呵,就打印出多少條數(shù)據(jù),只是會(huì)有1秒的延遲隧熙,更想象中的效果不一樣片挂。
后臺(tái)看了Vue的官方實(shí)例,修改代碼為贞盯,得到了我想要的效果音念,即以一秒鐘為單位,控制臺(tái)輸入input里的值躏敢,多余的被判定為“抖動(dòng)”的輸入闷愤,不會(huì)在控制臺(tái)打印。
// 正確示例
// 加載到vue原型鏈上的lodash在method函數(shù)后的定義的地方取不到件余,重新引了一遍
import _ from 'lodash'
export default {
methods: {
// 加載到原型鏈上的lodash讥脐,在getRemote后取不到
// 注意,這里debounce中的第一個(gè)參數(shù)蛾扇,不能寫成箭頭函數(shù)攘烛,否則魏滚,取不到this
getRemote: _.debounce(function () {
console.log('此處向后臺(tái)發(fā)起請(qǐng)求:', this.searchText)
}, 1000),
search () {
this.getRemote()
}
}
}
得到想要的結(jié)果镀首,但是還是留了三個(gè)疑問:
1.為什么在main.js中引入Vue原型鏈上的lodash在getRemote后不能用?
2.為什么getRemote的debounce第一個(gè)參數(shù)寫成箭頭函數(shù)就取不到this鼠次?
3.最后一個(gè)正確示例和倒數(shù)第一個(gè)錯(cuò)誤示例的寫法更哄,原理上的區(qū)別是什么芋齿?