手动实现发布订阅

class EventEmitter {
  constructor() {
    // 事件对象,存放订阅的名字和事件
    this.events = {};
  }
  // 订阅事件的方法
  on(eventName,callback) {
    if (!this.events[eventName]) {
      // 注意数据,一个名字可以订阅多个事件函数
      this.events[eventName] = [callback];
    } else  {
      // 存在则push到指定数组的尾部保存
      this.events[eventName].push(callback)
    }
  }
  // 触发事件的方法
  emit(eventName) {
    // 遍历执行所有订阅的事件
    this.events[eventName] && this.events[eventName].forEach(cb => cb());
  }
}
class Subject { // 被观察者 学生
  constructor(name) {
    this.state = '开心的'
    this.observers = []; // 存储所有的观察者
  }
  // 收集所有的观察者
  attach(o){ // Subject. prototype. attch
    this.observers.push(o)
  }
  // 更新被观察者 状态的方法
  setState(newState) {
    this.state = newState; // 更新状态
    // this 指被观察者 学生
    this.observers.forEach(o => o.update(this)) // 通知观察者 更新它们的状态
  }
}

class Observer{ // 观察者 父母和老师
  constructor(name) {
    this.name = name
  }
  update(student) {
    console.log('当前' + this.name + '被通知了', '当前学生的状态是' + student.state)
  }
}

let student = new Subject('学生'); 

let parent = new Observer('父母'); 
let teacher = new Observer('老师'); 

// 被观察者存储观察者的前提,需要先接纳观察者
student. attach(parent); 
student. attach(teacher); 
student. setState('被欺负了');

手动实现Object.freeze

function myFreeze(obj){ // 判断参数是否为Object类型,如果是就封闭对象,循环遍历对象。去掉原型属性,将其writable特性设置为false if(obj instanceof Object){ Object.seal(obj); // 封闭对象 for(let key in obj){ if(obj.hasOwnProperty(key)){ Object.defineProperty(obj,key,{ writable:false // 设置只读 }) // 如果属性值依然为对象,要通过递归来进行进一步的冻结 myFreeze(obj[key]); } } } }

function isPromise (val) {
  return typeof val.then === 'function'; // (123).then => undefined
}

Promise.all = function(promises) {
  return new Promise((resolve, reject) => {
    let arr = []; // 存放 promise执行后的结果
    let index = 0; // 计数器,用来累计promise的已执行次数
    const processData = (key, data) => {
      arr[key] = data; // 不能使用数组的长度来计算
      /*
        if (arr.length == promises.length) {
          resolve(arr);  // [null, null , 1, 2] 由于Promise异步比较慢,所以还未返回
        }
      */
     if (++index === promises.length) {
      // 必须保证数组里的每一个
       resolve(arr);
     }
    }
    // 遍历数组依次拿到执行结果
    for (let i = 0; i < promises.length; i++) {
      let result = promises[i];
      if(isPromise(result)) {
        // 让里面的promise执行,取得成功后的结果
        // data promise执行后的返回结果
        result.then((data) => {
          // 处理数据,按照原数组的顺序依次输出
          processData(i ,data)
        }, reject)  // reject本事就是个函数 所以简写了
      } else {
        // 1 , 2
        processData(i ,result)
      }
    }
  })
}

最后更新于

这有帮助吗?