VSCode源码分析 - 事件分发

目录

事件分发

event

src/vs/base/common/event.ts

程序中常见使用once方法进行事件绑定, 给定一个事件,返回一个只触发一次的事件,放在匿名函数返回

  1. export function once<T>(event: Event<T>): Event<T> {
  2. return (listener, thisArgs = null, disposables?) => {
  3. // 设置次变量,防止事件重复触发造成事件污染
  4. let didFire = false;
  5. let result: IDisposable;
  6. result = event(e => {
  7. if (didFire) {
  8. return;
  9. } else if (result) {
  10. result.dispose();
  11. } else {
  12. didFire = true;
  13. }
  14. return listener.call(thisArgs, e);
  15. }, null, disposables);
  16. if (didFire) {
  17. result.dispose();
  18. }
  19. return result;
  20. };
  21. }

循环派发了所有注册的事件, 事件会存储到一个事件队列,通过fire方法触发事件

private _deliveryQueue?: LinkedList<[Listener, T]>;//事件存储队列

  1. fire(event: T): void {
  2. if (this._listeners) {
  3. // 将所有事件传入 delivery queue
  4. // 内部/嵌套方式通过emit发出.
  5. // this调用事件驱动
  6. if (!this._deliveryQueue) {
  7. this._deliveryQueue = new LinkedList();
  8. }
  9. for (let iter = this._listeners.iterator(), e = iter.next(); !e.done; e = iter.next()) {
  10. this._deliveryQueue.push([e.value, event]);
  11. }
  12. while (this._deliveryQueue.size > 0) {
  13. const [listener, event] = this._deliveryQueue.shift()!;
  14. try {
  15. if (typeof listener === 'function') {
  16. listener.call(undefined, event);
  17. } else {
  18. listener[0].call(listener[1], event);
  19. }
  20. } catch (e) {
  21. onUnexpectedError(e);
  22. }
  23. }
  24. }
  25. }