The singleton pattern and publish and subscribe pattern are mainly used

The first singleton implements an event class

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(); }}Copy the code

Then implement the Promise class with a publish subscription, and call the static function initInstance of the EventBus class to generate a unique instance that can be shared among multiple Promise objects.

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; }}Copy the code

The usage method is as follows:

      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');
      });
Copy the code

This completes the basic function; But it’s still a long way from a full promise;