一道面试题引发的思考-promise.all实现

167 阅读1分钟

主要用到单例模式和发布订阅模式

首先单例实现一个事件类

      class EventBus {
        constructor() {
          this.instance = {}
        }

        listen(event,cb) {
          this.instance[event] = cb;
        }

        emit(event) {
          if (this.instance[event]) {
            this.instance[event]();
          }
        }

        static getInstance() {
          return this.instance;
        }

        static initInstance() {
          this.instance = new EventBus();
        }
      }

然后用发布订阅实现promise类,调用eventbus类的静态函数initInstance,生成唯一实例,这样可以在多个promise对象中共享;

      EventBus.initInstance();

      class Promise {
        static promises = [];

        state = 'pending';

        event = null;

        callbacks = [];

        intance = null;

        constructor(fn) {
          fn.call(this, this.resolve, this.reject);
        }

        static getInstance() {
          return this.intance;
        }

        static init() {
          this.instance = new Promise(()=>{});
        }

        static all(args, cb) {
          Promise.init();
          const self = this.instance;

          const event = EventBus.getInstance();

          args.forEach((fn, index) => {
            Promise.promises.push(fn);
          });

          event.listen('change', function () {
            console.log('change',self.callbacks)

            var result = true;
            let i =0;

            while(Promise.promises[i]) {
              if(Promise.promises[i].state !== 'fullfill') {
                result = false;
                break;
              }
              i++;
            }

            if (result && self.callbacks.length > 0) {
              self.callbacks.forEach(callback=>callback());
            }
          });

          return this.instance;
        }

        resolve = () => {
          this.state = 'fullfill';
          const event = EventBus.getInstance();
          event.emit('change');
        };

        reject = () => {
          this.state = 'reject';
          const event = EventBus.getInstance();
          event.emit('change');
        };

        then = (cb) => {
          this.callbacks.push(cb);
          return this;
        }
      }

使用方法如下:

      var promise1 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve();
        }, 0);
      });

      var promise2 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve();
        }, 1000);
      });

      var promise3 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve();
        }, 2000);
      });

      Promise.all([promise1, promise2, promise3]).then(function () {
        console.log('done');
      });

这样就完成基本功能;不过对于完整的promise还差很多;