收集多次请求合并为一次请求

Posted on Jun 17, 2022

每次请求从原来调用接口改为调collector方法,该方法返回promise,将promise的resolve注册到事件中。在时间窗口内的所有请求的参数会被收集。

在截流函数中发起真正的请求,请求结束后消费掉事件,也会触发promise的resolve。

import { throttle } from 'lodash';

export default class PatchMatch {
  private constructor() {
    this.bus = new EventBus();
  }

  public collector = (id, param) => {
    this.params.push(param);
    this.runner();
    return new Promise((resolve, reject) => {
      this.bus.on(id, resolve);
    });
  };

  private bus: EventBus;

  private params: any[] = [];

  private runner = throttle(() => {
    this.doPatchMatch();
    this.params = [];
  }, 100);

  private doPatchMatch = () => {
    fetch(`${urls.bizFormExtra.patchMatch}`, this.params).then(result => {
      const budgetAccountItems: Array<any> = result.data.data.itemBudgetAccounts;
      budgetAccountItems.forEach(bItem => {
        this.bus.emit(bItem.itemId, bItem);
      });
    });
  };
}

class EventBus {
  public on = (eventName, callback) => {
    this.eventMap[eventName] = callback;
  };
  private eventMap: { [key: string]: Function } = {};
  public emit = (eventName, ...args) => {
    const callback = this.eventMap[eventName];
    if (callback) {
      callback(...args);
      this.eventMap[eventName] = undefined
    }
  };
}