5. 手写throttle()并支持leading 和 trailing

中等难度  -通过 / -执行

该题目是4. 手写throttle()的后续,请先完成第4题。

本题目中你需要实现一个增强的throttle(),使其支持第三个参数option: {leading: boolean, trailing: boolean}

  1. leading: 是否立即执行
  2. trailing: 是否在冷却后执行

4. 手写throttle() 实际上是 {leading: true, trailing: true}的特殊情形。

具体说明

同样地按照之前的3单位的throttle来举例。

ABC ─ ─ D ─ ─ ─ ─ ─ ─ E ─ ─ FG 

{leading: true, trailing: true}来throttle后,我们得到

A ─ ─ ─ C ─ ─ ─ D ─ ─ ─ ─ E ─ ─ ─ G 

如果是 {leading: false, trailing: true},A 和 E 被跳过了

─ ─ ─ ─ C ─ ─ ─ D ─ ─ ─ ─ ─ ─ ─ G 

如果是 {leading: true, trailing: false},只有 A D E 被保留

A ─ ─ ─ ─ D ─ ─ ─ ─ ─ ─ E

如果是 {leading: false, trailing: false},显而易见,什么都不会发生

注意

  1. 请按照以上spec完成代码。以上逻辑和lodash.throttle()并不完全一致

  2. 因为 window.setTimeoutwindow.clearTimeout 并不精确。所以在test你写的代码的时候,这两个方法会被替换为静态的实现。不过不用担心,interface是一样的。

大概会按照以下的样子进行代码测试。

let currentTime = 0

const run = (input) => {
  currentTime = 0
  const calls = []

  const func = (arg) => {
     calls.push(`${arg}@${currentTime}`)
  }

  const throttled = throttle(func, 3)
  input.forEach((call) => {
     const [arg, time] = call.split('@')
     setTimeout(() => throttled(arg), time)
  })
  return calls
}

expect(run(['A@0', 'B@2', 'C@3'])).toEqual(['A@0', 'C@3'])

始终思考更好的解决办法

(1)
(127)