在JavaScript中实现防抖Promise

JavaScriptJavaScriptBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,我们将探索如何在JavaScript中创建一个返回Promise的防抖函数。我们将学习如何延迟调用一个函数,直到指定的时间过去,以及如何处理在此期间返回的多个Promise,以确保它们都返回相同的数据。在本实验结束时,你将对如何在JavaScript项目中使用Promise实现防抖有深入的理解。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL javascript(("`JavaScript`")) -.-> javascript/BasicConceptsGroup(["`Basic Concepts`"]) javascript(("`JavaScript`")) -.-> javascript/AdvancedConceptsGroup(["`Advanced Concepts`"]) javascript(("`JavaScript`")) -.-> javascript/ToolsandEnvironmentGroup(["`Tools and Environment`"]) javascript/BasicConceptsGroup -.-> javascript/variables("`Variables`") javascript/BasicConceptsGroup -.-> javascript/data_types("`Data Types`") javascript/BasicConceptsGroup -.-> javascript/arith_ops("`Arithmetic Operators`") javascript/BasicConceptsGroup -.-> javascript/comp_ops("`Comparison Operators`") javascript/BasicConceptsGroup -.-> javascript/obj_manip("`Object Manipulation`") javascript/AdvancedConceptsGroup -.-> javascript/async_prog("`Asynchronous Programming`") javascript/AdvancedConceptsGroup -.-> javascript/destr_assign("`Destructuring Assignment`") javascript/AdvancedConceptsGroup -.-> javascript/spread_rest("`Spread and Rest Operators`") javascript/ToolsandEnvironmentGroup -.-> javascript/debugging("`Debugging`") subgraph Lab Skills javascript/variables -.-> lab-28257{{"`在JavaScript中实现防抖Promise`"}} javascript/data_types -.-> lab-28257{{"`在JavaScript中实现防抖Promise`"}} javascript/arith_ops -.-> lab-28257{{"`在JavaScript中实现防抖Promise`"}} javascript/comp_ops -.-> lab-28257{{"`在JavaScript中实现防抖Promise`"}} javascript/obj_manip -.-> lab-28257{{"`在JavaScript中实现防抖Promise`"}} javascript/async_prog -.-> lab-28257{{"`在JavaScript中实现防抖Promise`"}} javascript/destr_assign -.-> lab-28257{{"`在JavaScript中实现防抖Promise`"}} javascript/spread_rest -.-> lab-28257{{"`在JavaScript中实现防抖Promise`"}} javascript/debugging -.-> lab-28257{{"`在JavaScript中实现防抖Promise`"}} end

防抖Promise

要创建一个返回Promise的防抖函数,该函数会延迟调用提供的函数,直到自上次调用以来至少经过了 ms 毫秒,请按以下步骤操作:

  1. 每次调用防抖函数时,使用 clearTimeout() 清除当前挂起的超时,然后使用 setTimeout() 创建一个新的超时,该超时会延迟调用函数,直到至少经过了 ms 毫秒。
  2. 使用 Function.prototype.apply()this 上下文应用于函数并提供必要的参数。
  3. 创建一个新的 Promise,并将其 resolvereject 回调添加到挂起的Promise堆栈中。
  4. 当调用 setTimeout() 时,复制当前堆栈(因为在提供的函数调用与其解析之间它可能会改变),清除它并调用提供的函数。
  5. 当提供的函数解析/拒绝时,使用返回的数据解析/拒绝堆栈中的所有Promise(在调用函数时复制)。
  6. 省略第二个参数 ms,将超时设置为默认的 0 毫秒。

以下是 debouncePromise() 函数的代码:

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

以下是如何使用 debouncePromise() 的示例:

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);
// 两次都会输出 ['resolved', 'bar']

总结

恭喜你!你已经完成了防抖Promise实验。你可以在LabEx中练习更多实验来提升你的技能。

您可能感兴趣的其他 JavaScript 教程