手写节流函数

简介: JS查漏补缺系列是我在学习JS高级语法时做的笔记,通过实践费曼学习法进一步加深自己对其的理解,也希望别人能通过我的笔记能学习到相关的知识点。这一次我们来试着手写节流函数

节流的基本实现逻辑
image.png

基本实现


console.log(`发送了第${++counter}次网络请求`)

}

// 节流处理
inputEl.oninput = throttle(inputChange, 2000)

function throttle(fn, interval, options) {
// 1.记录上一次的开始时间
let lastTime = 0

// 2.事件触发时, 真正执行的函数
const _throttle = function() {

// 2.1.获取当前事件触发时的时间
const nowTime = new Date().getTime()

// 2.2.使用当前触发的时间和之前的时间间隔以及上一次开始的时间, 计算出还剩余多长时间需要去触发函数
const remainTime = interval - (nowTime - lastTime)
if (remainTime <= 0) {
  // 2.3.真正触发函数
  fn()
  // 2.4.保留上次触发的时间
  lastTime = nowTime
}

}

return _throttle
}

功能优化——leading实现
:::info
有时候我们不想第一次输入的时候就发送请求,这时候我们最好做一个可选项供用户选择第一次的时候是否发送请求(leading: true/false)
:::

function throttle(fn, interval, options = { leading: true }) {
const { leading } = options
let lastTime = 0

const _throttle = function() {

const nowTime = new Date().getTime()
if (!lastTime && !leading) lastTime = nowTime

const remainTime = interval - (nowTime - lastTime)
if (remainTime <= 0) {
  fn()
  lastTime = nowTime
}

}
return _throttle
}

功能优化——trailing 实现
:::info
用户在10s内输出了一些内容后停止输出,因为 “ 与上一次发送请求时的间隔不为10s“ 而没有发送请求
用户需求:想要在停止输出的10s后发送请求,即使最后一次输出没有达到与上一次发送请求的间隔为10s的要求
:::

function throttle(fn, interval, options = { leading: true, trailing: false }) {
const { leading, trailing } = options
let lastTime = 0
let timer = null


const _throttle = function() {

const nowTime = new Date().getTime()
if (!lastTime && !leading) lastTime = nowTime

const remainTime = interval - (nowTime - lastTime)
if (remainTime <= 0) {
  // 在最后一次达到要求的情况下是不需要加上定时器的,要取消掉
  if (timer) {
    clearTimeout(timer)
    timer = null
  }
  fn()
  lastTime = nowTime
  return  // return是为了防止被加上下面的定时器
}

if (trailing && !timer) {
  timer = setTimeout(() => {
    timer = null
    lastTime = !leading ? 0: new Date().getTime()
    fn()
  }, remainTime)
}

}

return _throttle
}

功能优化——this、参数改进
:::info
与防抖中this、参数改进使用的方法是一样的,用apply进行绑定this、arg,用剩余函数...arg接收参数
:::

function throttle(fn, interval, options = { leading: true, trailing: false }) {
const { leading, trailing } = options
let lastTime = 0
let timer = null
// 用剩余函数...arg接收参数
const _throttle = function(...args) {

const nowTime = new Date().getTime()
if (!lastTime && !leading) lastTime = nowTime

const remainTime = interval - (nowTime - lastTime)
if (remainTime <= 0) {
  if (timer) {
    clearTimeout(timer)
    timer = null
  }

  //用apply进行绑定this、arg
  fn.apply(this, args)
  lastTime = nowTime
  return
}

if (trailing && !timer) {
  timer = setTimeout(() => {
    timer = null
    lastTime = !leading ? 0: new Date().getTime()
    fn.apply(this, args)
  }, remainTime)
}

}

return _throttle
}

功能优化——取消功能
:::info
场景:用户在输入东西之后防抖函数发送请求之前按到退出键退出了界面或按了取消按钮,这时我们就不用再发送请求
:::


// 在原来的外部script代码中添加取消功能的代码
_throttle.cancel = function() {

if(timer) clearTimeout(timer)
timer = null
lastTime = 0

}

功能优化——函数返回值
:::info
使用Promise来实现,resolve( ) 将结果进行回调出去
:::

function throttle(fn, interval, options = { leading: true, trailing: false }) {
const { leading, trailing, resultCallback } = options
let lastTime = 0
let timer = null

const _throttle = function(...args) {

return new Promise((resolve, reject) => {
  const nowTime = new Date().getTime()
  if (!lastTime && !leading) lastTime = nowTime

  const remainTime = interval - (nowTime - lastTime)
  if (remainTime <= 0) {
    if (timer) {
      clearTimeout(timer)
      timer = null
    }

    const result = fn.apply(this, args)
    if (resultCallback) resultCallback(result)
    resolve(result)
    lastTime = nowTime
    return
  }

  if (trailing && !timer) {
    timer = setTimeout(() => {
      timer = null
      lastTime = !leading ? 0: new Date().getTime()
      const result = fn.apply(this, args)
      if (resultCallback) resultCallback(result)
      resolve(result)
    }, remainTime)
  }
})

}

_throttle.cancel = function() {

if(timer) clearTimeout(timer)
timer = null
lastTime = 0

}

return _throttle
}

目录
相关文章
|
6月前
15 # 手写 throttle 节流方法
15 # 手写 throttle 节流方法
45 0
|
前端开发
封装防抖函数和节流函数
封装防抖函数和节流函数
72 0
|
3月前
|
存储 前端开发 JavaScript
面试时让你手写一个防抖和节流优化,你能写出来吗?(二)
面试时让你手写一个防抖和节流优化,你能写出来吗?(二)
|
3月前
|
前端开发 UED
面试时让你手写一个防抖和节流优化,你能写出来吗?(一)
面试时让你手写一个防抖和节流优化,你能写出来吗?(一)
|
4月前
|
缓存 开发框架 前端开发
前端性能优化【前端必备】(含懒加载,手写防抖、节流等)
前端性能优化【前端必备】(含懒加载,手写防抖、节流等)
72 4
|
前端开发
手写防抖
手写防抖
61 0
|
6月前
|
前端开发 JavaScript 程序员
【面试题】 js-面试官要求手写节流防抖?
【面试题】 js-面试官要求手写节流防抖?
|
6月前
14 # 手写 debounce 防抖方法
14 # 手写 debounce 防抖方法
46 1
|
6月前
|
前端开发 JavaScript UED
手写一个防抖
手写一个防抖
41 0
|
6月前
|
前端开发
【前端学习】—函数防抖(十)
【前端学习】—函数防抖(十)