手动实现发布订阅
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)
}
}
})
}
最后更新于
这有帮助吗?