溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

javascript實(shí)現(xiàn)函數(shù)防抖與節(jié)流

發(fā)布時(shí)間:2020-05-25 15:03:16 來(lái)源:億速云 閱讀:231 作者:鴿子 欄目:web開發(fā)

概念理解

防抖:在事件被觸發(fā)n秒后再執(zhí)行回調(diào),如果在這n秒內(nèi)又被觸發(fā),則重新計(jì)時(shí)。

節(jié)流:規(guī)定在一個(gè)單位時(shí)間內(nèi),只能觸發(fā)一次函數(shù)。如果這個(gè)單位時(shí)間內(nèi)觸發(fā)多次函數(shù),只有一次生效。

js函數(shù)防抖與節(jié)流的區(qū)別:

函數(shù)防抖是某一段時(shí)間內(nèi)只執(zhí)行一次,而函數(shù)節(jié)流是間隔時(shí)間執(zhí)行。

個(gè)人踩坑

1、通過(guò)理解函數(shù)防抖與函數(shù)節(jié)流的概念后,使用閉包實(shí)現(xiàn)函數(shù)防抖和節(jié)流,沒(méi)有考慮到對(duì)于節(jié)流,如果用戶在下一次請(qǐng)求之前已輸入完畢,但是此時(shí)不會(huì)再進(jìn)行請(qǐng)求,則會(huì)導(dǎo)致最后輸入的文字獲取其他事件改變不發(fā)請(qǐng)求,即漏請(qǐng)求,所以需要加一個(gè)setTimeout兜底函數(shù),且在每次準(zhǔn)備請(qǐng)求的時(shí)候,設(shè)一個(gè)flag,即是否已經(jīng)發(fā)送請(qǐng)求,如果走了正常周期發(fā)送請(qǐng)求,改為true,否則即為false,走setTimout,讓setTimeout比剩余事件略長(zhǎng)一些,優(yōu)先走節(jié)流定時(shí)器請(qǐng)求;

2、如果使用箭頭函數(shù),則不需要保存this。

代碼實(shí)現(xiàn)

 <div>
    <div>
        <input type="text" id="unDebounce">
    </div>
    <div>
        <input type="text" id="debounce">
    </div>
    <div>
        <input type="text" id="throttle">
    </div>
</div>
// 函數(shù)防抖節(jié)流
var elem1 = document.getElementById("unDebounce")
var elem2 = document.getElementById("debounce")
var elem3 = document.getElementById("throttle")
// 不防抖
function ajax1(value){
    console.log("不防抖,不節(jié)流")
    console.log(value)
}
elem1.addEventListener('keyup',function (e) {
    ajax1(e.target.value);
})
// 防抖
function ajax2(value) {
    console.log(value)
}
function debounce(func,delay){
    console.log("函數(shù)防抖")
    let timer = null;
    return function(...args){
        if(timer){
            console.log("清除定時(shí)器")
            clearTimeout(timer)
        }
        timer = setTimeout(()=>{
            console.log("重新計(jì)時(shí)")
            func.call(this,...args)
        },delay)
    }
}
let debounceFn = debounce(ajax2,1000)
elem2.addEventListener('keyup',function (e) {
    debounceFn(e.target.value);
})
// // 節(jié)流
function ajax3(value){
    console.log(value)
}
function throttle(func,delay){
    console.log("函數(shù)節(jié)流")
    let lastTime = 0;
    let timer = null;
    return function (...args) {
        let flag = false ; // 還沒(méi)發(fā)送數(shù)據(jù)
        let now = +new Date().getTime();
        if(timer){
            clearTimeout(timer)
        }
        if(now-lastTime>=delay){
            console.log("當(dāng)前時(shí)間大于設(shè)定時(shí)間,開始執(zhí)行函數(shù)")
            func.apply(this,args)
            console.log("time1",new Date().getTime())
            lastTime = now;
            flag = true; // 發(fā)送了數(shù)據(jù)
        }else{
            timer = setTimeout(()=>{
                if(!flag){ // 如果沒(méi)有發(fā)送數(shù)據(jù)成功,再走這個(gè),兜底發(fā)送請(qǐng)求
                    func.apply(this,args)
                    console.log("time2",new Date().getTime())
                }
            },delay-(now-lastTime)+1000) // setTimeout多一些,優(yōu)先執(zhí)行周期性請(qǐng)求
        }
    }
}
let throttleFn = throttle(ajax3,5000)
elem3.addEventListener('keyup',function (e) {
    throttleFn(e.target.value);
})

以上就是js如何實(shí)現(xiàn)函數(shù)防抖與節(jié)流的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注億速云其它相關(guān)文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI