vueuse filter 解析

createFilterWrapper

js 复制代码
/**
 * @internal
 */
export function createFilterWrapper<T extends AnyFn>(filter: EventFilter, fn: T) {
  function wrapper(this: any, ...args: ArgumentsType<T>) {
    return new Promise<Awaited<ReturnType<T>>>((resolve, reject) => {
      // make sure it's a promise
      Promise.resolve(filter(() => fn.apply(this, args), { fn, thisArg: this, args }))
        .then(resolve)
        .catch(reject);
    });
  }
  return wrapper;
}

createFilterWrapper 返回的函数wrapper就是被eventFilter处理过的函数,比如传入的fn希望被节流,当filterthrottleFilter,那么wrapper就是一个节流的函数。

// 创建一个节流函数(只创建一次)

js 复制代码
const throttledFn = useThrottleFn(() => {
  console.log('throttled function');
});

// 多次调用这个节流函数(每次调用会创建一个新Promise,但执行会受到节流控制)

js 复制代码
throttledFn();
throttledFn();
throttledFn();

也就是当执行 throttledFn()就会执行 filter(() => fn.apply(this, args), { fn, thisArg: this, args })

本质上这个filter 才是最终的「节流了的函数」,即 throttledFn <==> filter

和lodash一样节流/防抖,如何用createFilterWrapper实现呢?

const fn = _.debounce(fn, 200, { maxWait: 1000 }) ,使用createFilterWrapper 如下:

js 复制代码
fn = createFilterWrapper(
    debounceFilter(200, { maxWait: 1000 }),
    fn,
  );

throttleFilter

js 复制代码
// throttleFilter函数内返回的filter

const filter: EventFilter = (_invoke) => {
    const duration = toValue(ms);
    const elapsed = Date.now() - lastExec;
    const invoke = () => lastValue = _invoke();

    clear();

    if (duration <= 0) {
      lastExec = Date.now();
      return invoke();
    }

    if (elapsed > duration && (leading || !isLeading)) {
      lastExec = Date.now();
      invoke();
    } else if (trailing) {
      lastValue = new Promise((resolve, reject) => {
        lastRejector = rejectOnCancel ? reject : resolve;
        timer = setTimeout(() => {
          lastExec = Date.now();
          isLeading = true;
          resolve(invoke());
          clear();
        }, Math.max(0, duration - elapsed));
      });
    }

    if (!leading && !timer) timer = setTimeout(() => isLeading = true, duration);

    isLeading = false;
    return lastValue;
  };
相关推荐
大龄码农有梦想15 小时前
Vue + BPMN.js + Camunda:搭建企业级流程设计器完整实践
javascript·vue.js·流程设计器·bpmn.js·bpmn·流程审批·工作流设计器
岁岁种桃花儿19 小时前
Vue核心语法第一篇:Vue是什么?
前端·javascript·vue.js
你挚爱的强哥20 小时前
【chromeDownload】自定义组件:多用于登录框底部提供下载Chrome谷歌浏览器的链接
前端·vue.js·chrome
daols8821 小时前
vue 甘特图 vxe-gantt 任务条拖拽自动更新日期
javascript·vue.js·甘特图
java1234_小锋1 天前
Vue3专题 - 组件基础
vue.js·vite
阿懂在掘金2 天前
同一份弹窗我重构了三次:从 v-model 地狱到路由式调用,终于治好了模板臃肿
前端·vue.js·前端框架
小锋java12342 天前
【技术专题】Vue3 - 生命周期
vue.js·vite
淘源码d2 天前
从0到1搭建医院随访系统:模块拆解 + 技术选型 + 部署方案
数据库·vue.js·源码·随访
Highcharts.js2 天前
Vue 3 + Highcharts Boost 可视化加速模块的完整示例
javascript·vue.js·可视化·boost·highcharts·图表渲染·加速模块
夏幻灵2 天前
从语法坑点到 JS 内存底层:Vue 3 watch 侦听器深度全解
开发语言·javascript·vue.js