道招

前端也会需要一个消费队列

如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!

前端也会需要一个消费队列

现在我们已经习惯了模块化,微服务化,这样的确带来了很多的好处,但是有时也会有些小麻烦。比如: A组件和B组件各要调用一个接口,并且根据接口调用完成后执行回调,要求A组件的回调较B组件的先执行。 如果是在同一个组件里面,我们比较容易的控制接口的调用时机(同时调用两个接口),并且通过Promise.all来完成这个需求。但是在两个组件里面一不好控制接口的调用时机,二不好控制回调执行顺序。 这时我们就需要一个事件通知系统和一个消费队列了,在微服务中事件系统一般都有的,我们只需要额外加一个消费队列就行了。

首先我们理一下:

  1. 多个组件的回调到位的顺序不可控(可能存在后执行的回调先到位,有的可能得根据接口调用结果来确定回调的内容)
  2. 开发者自己是知道各个回调期望的执行顺序的。将各个回调指定设置顺序放置于队列中,队列讲回调排序后顺序执行。
  3. 需不需要设置回调的最后执行时间,不能因为一个排序前面的回调没有成功进入队列(比如接口调用失败导致),其它的回调都得不到执行

简单的实现代码(typescript)如下:

interface task {
  id: number;
  max: number;
  maxMs?: number;
  callback: Function;
}

export default class ConsumeQueue {
  private queue: task[];
  timeId;
  constructor() {
    this.queue = [];
    this.timeId = null;
  }

  guaranteed(ms) {
    clearTimeout(this.timeId);
    this.timeId = setTimeout(() => {
      if (this.queue.length>0) {
        this.run();
      }
    }, ms);
  }

  sort(): task[] {
    return this.queue.sort( (a: task, b: task) :number =>  {
      if (a.id < b.id) return -1;
      if (a.id > b.id) return 1;
      return 0;
    });
  }

  push(task) {
    this.queue.push(task);
    if (this.queue.length >= task.max) {
      this.run();
    }else if(task.maxMs){
     this.guaranteed(task.maxMs);
    }
  }

  run() {
    this.sort();
    this.exec();
  }

  exec() {
    const copied: task[] = this.queue.slice(0);
    this.queue.length = 0;
    copied.forEach((item: task) => {
      item.callback();
    });
  }
}

我们在每次向消费队列放置完回调就检查下队列里面的回调是不是都到齐了,到齐了就执行;如果没有到齐并且当前回调设置了最大等待时长,如果设置了就设置一个定时器,定时器到了就执行队列里面现有的回调。

更新时间:
上一篇:从vuecli3学习webpack记录(零)整体流程下一篇:vue-cli设置css不生效

相关文章

安装运行angular2

现在官方貌似推荐用typescript来开发Angular,访问官方网站http://angular.io,点击Get Started,就会跳转到https://angular.io/docs/ts/ 阅读更多…

关注道招网公众帐号
道招开发者二群