Skip to content

Latest commit

 

History

History
65 lines (52 loc) · 2.52 KB

debounce-promise.md

File metadata and controls

65 lines (52 loc) · 2.52 KB
标题 标签
debounce(防抖期约函数) function,promise(函数,期约)

创建一个返回期约的防抖动函数,但延迟调用提供的函数,直到自上次调用以来至少经过 ms 毫秒。在此期间返回的所有期约都将返回相同的数据。

  • 每次调用防抖函数时,使用 clearTimeout() 清除当前挂起的延迟函数并使用 setTimeout() 创建一个新的延迟函数,该延迟函数将延迟调用该函数,直到至少 ms 毫秒过去。
  • 使用 Function.prototype.apply()this 上下文应用于函数并提供必要的参数。
  • 创建一个新的 Promise 并将其解析和拒绝回调添加到待处理的 Promise 堆栈中。
  • 调用 setTimeout() 时,复制当前堆栈(因为它可以在提供的函数调用及其分辨率之间更改),清除它并调用提供的函数。
  • 当提供的函数解析/拒绝时,使用返回的数据解析/拒绝堆栈中的所有期约(在调用函数时复制)。
  • 省略第二个参数 ms,将延迟函数设置为默认值 0ms

代码如下:

const debouncePromise = (handler, ms) => {
  let timer = null;
  const pending = [];
  return (...args) =>
    new Promise((resolve, reject) => {
      clearTimeout(timer);
      timer = setTimeout(() => {
        const currentPending = [...pending];
        pending.length = 0;
        Promise.resolve(handler.apply(this, args)).then(
          data => {
            currentPending.forEach(({ resolve: res }) => res(data));
          },
          error => {
            currentPending.forEach(({ reject: rej }) => rej(error));
          }
        );
      }, ms);
      pending.push({ resolve, reject });
    });
};

ts 代码如下:

调用方式:

const fn = arg =>
  new Promise(resolve => {
    setTimeout(resolve, 1000, ['resolved', arg]);
  });
const debounced = debouncePromise(fn, 200);
debounced('foo').then(console.log);
debounced('bar').then(console.log);
// Will log ['resolved', 'bar'] both times

应用场景

以下是一个实战示例:

结果如下:

<iframe src="codes/javascript/html/debounce-promise.html"></iframe>