手写promise原理——高阶函数实现——函数柯里化原理——实现通用柯里化函数——函数订阅发布模式实现——手写观察者模式

1. 高阶函数

// 高阶函数: 如果一个函数的参数是一个函数(回调函数也是高阶函数的一种)
//  如果一个函数返回 一个函数 当前函数也是一个 高阶函数  

// 扩展当前业务代码 
function say(a,b){
	console.log("say",a,b);
}
// 给某个方法添加方法 在执行之前调用 
Function.prototype.before = function(callback){
	// let _this = this; // 让this 指向say  
	//return function(){
	//	callback();
		// 注意 this 
	//	this()  
	//}
	// 剩余运算符 ...args   ... 在函数参数里 把所有参数组成数组 在函数调用 表示展开 参数依次传入 
	return (...args)=>{
		// 箭头函数 没有this 和 arguments
		callback();
		this(...args); 
	}
}
let beforeSay = say.before(function(){
 	console.log('before.say');
});
// 之后调用 beforeSay
beforeSay("hello","word");

2. 函数柯里化

// 函数柯里化 函数反柯里化 

// 判断变量的类型 
// 常用的判断 类型的方法。 

 -  typeof  不能判断对象类型 ( 数组和 对象都是 Object );
 -  constructor 判断类型的构造  
 - instanceof  判断谁是谁 实例 (判断会存在不准确的情况) __proto__ ;
 - Object.prototype.toString.call() // 获取对象原型上的 toStiong 上的 this  是当前的对象 缺陷 不能判断谁是谁的实例	
 
 function istype(value,type){
	return Object.prototype.toString.call(value) === `[object ${type}]`;
};
// 方法的详细拆分 isType => isString isArray 
console.log(istype([],'Array'));
  // 柯里化
  function isType(type){
	return function(value){
		return Object.protottpe.toString.call(value) === `[Object ${type}]`
	}
}
let isString = isType('String'); // 创造固定类型函数
let isArray = isType('Array'); 
let Object = isType('Object');
console.log(isString('value'));
console.log([]);
// 实现通用函数柯里化 (通过一个通用的柯里化函数,实现函数的柯里化)
const currying = (fn,arr=[])=>{
	let len = fn.length; // 获取函数参数的个数
	return (...args)=>{
		let arg = arr.concat(args); // [...arr,...args]
		if(arg.length < len){
			return 	currying(fn,arg);
		}
		return fn(...arg);
	}
}
const add = (a,b,c,d,e)=>{
	return a + b + c + d + e;
}
let r = currying(add)(1)(2,3)(4,5);
isArray = curring(istype)('Array');
isString = curring(istype)('String');
console.log(isArray([]));
console.log(isString('hello'));

  1. 回调函数异步并发问题

// 多个异步请求 同时获取 最终结果
const after = (times, callback) => () => {
  if (--times === 0) {
    callback();
  }
};
const newFn = after(3, () => {
  console.log("ok");
});
  1. 发布订阅模

// on-emit 模式
 let man = {}
 let fs = require('fs'); // file system 
 let even = { // 发布和订阅没有明星的关系
	 arr:[],
	 on(fn){
		 this.arr.push(fn);
	 },
	 emit(){ 
		 this.arr.forEach(fn=>fn());
	 },
 };
 even.on(()=>{console.log("读取数据")})
 fs.readFile('./name.txt','utf8',(err,data)=>{
	 man.name = data;
	 // console.log(man,'1')
	even.emit();
 })
 fs.readFile('./age.txt','utf8',(err,data)=>{
 	 man.age = data;
	 // console.log(man,"3")
	 even.emit();
 })
 even.on(()=>{
	 if(Object.keys(man).length !==2)return
	 console.log("读取数据",man)
 })			
  1. 观察者模式

// 观察者模式  观察者 和被观察者 观察者需要发到被观察者中 被观察者发生变化 需要告之被观察者

// 内部也是基于订阅发布者模式  收集观察者 状态变化 通知观察者 

  class Subject { // 被观察者 
		constructor(name) {
		    this.name = name;
			this.state = "面无表情";
			this.observers = [];
		}
		attach(o){
			this.observers.push(o);
		}
		SetState(newState){
			this.state = newState;
			this.observers.forEach(o=>o.update(this))
		}
	  
  }
  class Observer{
	  constructor(name) {
	      this.name = name;
		  
	  }
	  update(baby){
		  console.log(`这个${this.name}被通知了${baby.name}${baby.state}`);
	  }
  }
  let baby = new Subject('张太阳');
  let parent = new Observer('爸爸');
  let mother = new Observer('妈妈');
  baby.attach(parent);
  baby.attach(mother);
  baby.SetState('饿哭了');
  1. 简单的promise

promise 的简单理解

//  promise 的概念 以及特点

// https://promisesaplus.com/   promisea+ 规范 
//  https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

//  promise Es6 内部已经完全实现  ie 不支持promis , 需要 polyfill  es6-promise 

// promise	的产生原因 用于解决异步问题

//  1. 异步 请求的多并发问题 (希望同步最终结果) promise.all 
//  2. 异步请求问题(异步回调儿地狱-回调金字塔问题)上一个请求的输出是下一个请求的参数 Promise 的链式调用 可以解决这个问题
//  3. 缺陷 还是基于回调的 
	
// promise 有三个状态: 成功态(resolve) 失败态(reject) 等待态(pending) (不成功也不失败)
// promise 就是一个类 
// 用户自己决定失败的原因和成功的原因 成功和失败也是用户自己定义的 取决于用户调了那个方法 
// 1.promise 执行器是默认立即 执行
// 2.promise 的每个实例都有一个 then 的方法 一个参数是成功的回调 一个参数是失败的回调  
// 3.如果执行函数的时候发生了异常(执行了异常的逻辑) 也会执行失败
// 4.promise 一旦成功就不可能失败 一旦失败就不可能成功 
let promise = new Promise((resolve,reject)=>{
	
	// throw new Error("失败了"); 
	console.log(1)
	reject("没有发工资");
	resolve("今天墨鱼了");
	
})
console.log(2);
console.log(promise);


promise.then((resole)=>{
	//  这里走的是成功的回调函数
	
	console.log( "success",resole);
},(reject)=>{
	//  这里走的是失败的回调函数  
	console.log("err",reject);
})

实现一个简单的promise

// promise 有三个状态 pending(等待态)  resolve(成功态) reject(失败态)
let PENDING = "PENDING"; // 等待态
let RESOLVE = "RESOLVE"; // 成功态
let REJECT = "REJECT"; // 失败态
// promise 是个类  创建一个promise 类
class Promise{
	constructor(executor){
        this.status = PENDING;
        this.value = undefined; // 成功的原因
        this.reason = undefined; // 失败的原因
        let resolve = (value)=>{
            if(this.status === "PEDING"){
                this.value = value;
                this.status = RESOLVE;
            }

        } // 不属于实例上的 是单独每个人都有的
        let reject = (reason)=>{
            if(this.status === "PENDING"){
                this.reason = reason;
                this.status = REJECT;
            }

        }
        // promise 发生了错误的逻辑也会 执行 失败
        try{
            executor(resolve,reject); // 这个是执行器 默认立即执行
        }catch (e) {
            console.log(e)
            reject(e);
        }
    }
    then(onFulfiled,onRjected){
        if(this.status === RESOLVE){
            onFulfiled(this.value);
        }
        if(this.status === REJECT){
            onRjected(this.reason);
        }
    }
}

promise 的 then 方法 实现

// promise 有三个状态 pending(等待态)  resolve(成功态) reject(失败态)
let PENDING = "PENDING"; // 等待态
let RESOLVE = "RESOLVE"; // 成功态
let REJECT = "REJECT"; // 失败态
// promise 是个类  创建一个promise 类
class Promise{
	constructor(executor){
        this.status = PENDING;
        this.value = undefined; // 成功的原因
        this.reason = undefined; // 失败的原因
        this.onResolvedCallbacks = []; // 成功的回调函数 集合
        this.onRejectedCallbacks =[]; // 失败的回调函数 集合
        let resolve = (value)=>{
            if(this.status === "PEDING"){
                this.value = value;
                this.status = RESOLVE;
                console.log(this.onResolvedCallbacks)
                this.onResolvedCallbacks.forEach(fn=>fn());
            }

        } // 不属于实例上的 是单独每个人都有的
        let reject = (reason)=>{
            if(this.status === "PENDING"){
                this.reason = reason;
                this.status = REJECT;
                console.log(this.onRejectedCallbacks)
                this.onRejectedCallbacks.forEach(fn=>fn());
            }

        }
        // promise 发生了错误的逻辑也会 执行 失败
        try{
            executor(resolve,reject); // 这个是执行器 默认立即执行
        }catch (e) {
            console.log(e)
            reject(e);
        }
    }
    then(onFulfiled,onRejected){
        console.log(1,this.onResolvedCallbacks)
        console.log(1,this.onRejectedCallbacks)
        if(this.status === RESOLVE){
            onFulfiled(this.value);
        }
        if(this.status === REJECT){
            onRejected(this.reason);
        }
    if(this.status === PENDING){

        this.onResolvedCallbacks.push(()=>{
            onFulfiled(this.value);
        })
        this.onRejectedCallbacks.push(()=>{
            onRejected(this.reason);
        })
    }
    }
}
module.exports = Promise;

promise 的 then的用法解析

let fs = require("fs");
//  error first 错误第一  异步方法 无法通过 try catch 捕获异常
// fs.readFile("./name.text","utf8",(err,data)=>{
//     console.log(data);
//     if(err){}
//     fs.readFile(data,"utf8",(err,data)=>{
//         if(err){}
//         console.log(data);
//     })
// });
// 写法没有问题 但是错误处理麻烦
// promis 可以解决上面的问题
function read(fillname){
    return new Promise((resolve, reject)=>{
         fs.readFile(fillname,"utf8",(err,data)=>{
             if(err)return reject(err)
             resolve(data)
         })
    })
}
// 1.promise 的 成功或失败的回调的 返回值 可以传递到外层的 then
// 2. 如果返回值为普通值 可以当下一个回调 then 的参数 可能有 promise 的情况(采用 promis的状态 判断下一次的 成功或者失败) 还有 error的情况 出错就一点会走下一次的失败
// 3. 错误处理 如果 自己没有错误处理 他会向下查找
// 4. 每次执行完promise.then 方法后返回的都是一个 "promise" (promise 一旦成功或者失败就不能修改)
read("./name.txt").then((data)=>{
    console.log(data);
    return read(data);
},(err)=>{
    console.log(err);
    throw new Error("错误");
}).then((data)=>{
    console.log("______",data);
},(err)=>{
    console.log("____",err+"错误");
})
// 这样就是通过了 链式调用解决了回调 嵌套问题

普通值的处理

// promise 有三个状态 pending(等待态)  resolve(成功态) reject(失败态)
let PENDING = "PENDING"; // 等待态
let RESOLVE = "RESOLVE"; // 成功态
let REJECT = "REJECT"; // 失败态
// promise 是个类  创建一个promise 类
class Promise {
    constructor(executor) {
        this.status = PENDING;
        this.value = undefined; // 成功的原因
        this.reason = undefined; // 失败的原因
        this.onResolvedCallbacks = []; // 成功的回调函数 集合
        this.onRejectedCallbacks = []; // 失败的回调函数 集合
        let resolve = (value) => {
            if (this.status === PENDING) {
                this.value = value;
                this.status = RESOLVE;
                console.log(this.onResolvedCallbacks)
                this.onResolvedCallbacks.forEach(fn => fn());
            }

        } // 不属于实例上的 是单独每个人都有的
        let reject = (reason) => {
            if (this.status === PENDING) {
                this.reason = reason;
                this.status = REJECT;
                console.log(this.onRejectedCallbacks)
                this.onRejectedCallbacks.forEach(fn => fn());
            }

        }
        // promise 发生了错误的逻辑也会 执行 失败
        try {
            executor(resolve, reject); // 这个是执行器 默认立即执行
        } catch (e) {
            console.log(e)
            reject(e);
        }
    }

    // 1.promise 的 成功或失败的回调的 返回值 可以传递到外层的 then
    // 2. 如果返回值为普通值 可以当下一个回调 then 的参数 可能有 promise 的情况(采用 promis的状态 判断下一次的 成功或者失败) 还有 error的情况 出错就一点会走下一次的失败
    // 3. 错误处理 如果 自己没有错误处理 他会向下查找
    // 4. 每次执行完promise.then 方法后返回的都是一个 "promise"(promise 一旦成功或者失败就不能修改)


    then(onFulfiled, onRejected) {
        // console.log(1, this.onResolvedCallbacks)
        // console.log(1, this.onRejectedCallbacks,this.status)

        let promise2 = new Promise((resolve,reject)=>{ // 为了实现链式调用
            if (this.status === RESOLVE) {

                let x =   onFulfiled(this.value);
                resolve(x);

            }
            if (this.status === REJECT) {
                onRejected(this.reason);
            }
            if (this.status === PENDING) {

                this.onResolvedCallbacks.push(() => {
                    onFulfiled(this.value);
                })
                this.onRejectedCallbacks.push(() => {
                    onRejected(this.reason);
                })
            }
        })
        return promise2
    }
}

module.exports = Promise;

promise2状态的处理

// promise 有三个状态 pending(等待态)  resolve(成功态) reject(失败态)
let PENDING = "PENDING"; // 等待态
let RESOLVE = "RESOLVE"; // 成功态
let REJECT = "REJECT"; // 失败态
let resolvePromise = (promise2,x,resolve,reject)=>{
    console.log(promise2,x,resolve,reject);
}
// promise 是个类  创建一个promise 类
class Promise {
    constructor(executor) {
        this.status = PENDING;
        this.value = undefined; // 成功的原因
        this.reason = undefined; // 失败的原因
        this.onResolvedCallbacks = []; // 成功的回调函数 集合
        this.onRejectedCallbacks = []; // 失败的回调函数 集合
        let resolve = (value) => {
            if (this.status === PENDING) {
                this.value = value;
                this.status = RESOLVE;
                console.log(this.onResolvedCallbacks)
                this.onResolvedCallbacks.forEach(fn => fn());
            }

        } // 不属于实例上的 是单独每个人都有的
        let reject = (reason) => {
            if (this.status === PENDING) {
                this.reason = reason;
                this.status = REJECT;
                console.log(this.onRejectedCallbacks)
                this.onRejectedCallbacks.forEach(fn => fn());
            }

        }
        // promise 发生了错误的逻辑也会 执行 失败
        try {
            executor(resolve, reject); // 这个是执行器 默认立即执行
        } catch (e) {
            console.log(e)
            reject(e);
        }
    }

    // 1.promise 的 成功或失败的回调的 返回值 可以传递到外层的 then
    // 2. 如果返回值为普通值 可以当下一个回调 then 的参数 可能有 promise 的情况(采用 promis的状态 判断下一次的 成功或者失败) 还有 error的情况 出错就一点会走下一次的失败
    // 3. 错误处理 如果 自己没有错误处理 他会向下查找
    // 4. 每次执行完promise.then 方法后返回的都是一个 "promise"(promise 一旦成功或者失败就不能修改)


    then(onFulfiled, onRejected) {
        // console.log(1, this.onResolvedCallbacks)
        // console.log(1, this.onRejectedCallbacks,this.status)

        let promise2 = new Promise((resolve,reject)=>{ // 为了实现链式调用
            if (this.status === RESOLVE) {
                setTimeout(()=>{
                    try{
                        let x =   onFulfiled(this.value);
                        resolvePromise(promise2,x,resolve,reject);
                    }catch (e) {
                        reject(e);
                    }

                },0)


            }
            if (this.status === REJECT  ) {

                setTimeout(()=>{
                    try{
                        let x =  onRejected(this.reason);
                        resolvePromise(promise2,x,resolve,reject);
                    }catch (e) {
                        reject(e);
                    }

                },0)
            }
            if (this.status === PENDING) {

                this.onResolvedCallbacks.push(() => {

                    setTimeout(()=>{
                        try{
                            let x =  onFulfiled(this.value);
                            resolvePromise(promise2,x,resolve,reject);
                        }catch (e) {
                            reject(e);
                        }

                    },0)
                })
                this.onRejectedCallbacks.push(() => {

                    setTimeout(()=>{
                        try{
                            let x =  onRejected(this.reason);
                            resolvePromise(promise2,x,resolve,reject);
                        }catch (e) {
                            reject(e);
                        }

                    },0)
                })
            }
        })
        return promise2
    }
}

module.exports = Promise;

**完整的promise **

// promise 有三个状态 pending(等待态)  resolve(成功态) reject(失败态)
let PENDING = "PENDING"; // 等待态
let RESOLVE = "RESOLVE"; // 成功态
let REJECT = "REJECT"; // 失败态
// resolvePromise 所有的 promise 都要遵循 bluebired q es6-romise
let resolvePromise = (promise2,x,resolve,reject)=>{
    // console.log(promise2,x,resolve,reject);
    // 循环引用
    if(promise2 === x){
        throw reject(new TypeError("TypeError: Chaining cycle detected for promise #<Promise>"))
    }
    let called = false;
    if(typeof x === 'object' && x != null || typeof x === "function"){
    //     要继续判断 有可能是 promise
       
        try {
            let then = x.then
            if(typeof then === "function"){ // 只能认为是个 promise了
                // x.then
                then.call(x,y=>{ // 根据 promise 的成功就走成功,失败就走失败
                    if(called)return;
                    called = true;
                    resolvePromise(promise2,y,resolve,reject)
                    // resolve(y)
                },e=>{
                    if(called)return;
                    called = true;
                    reject(e)
                })
            }else {

                resolve(x)
            }
        }catch (e) {
            // 防止失败了 再次成功
            if(called)return;
            called = true;
            reject(e) // 异常抛出
        }
    }else {
        resolve(x);
    }

    // 后续判断必须为严格模式  保证代码能和别的库 一起使用
}
// promise 是个类  创建一个promise 类
class Promise {
    constructor(executor) {
        this.status = PENDING;
        this.value = undefined; // 成功的原因
        this.reason = undefined; // 失败的原因
        this.onResolvedCallbacks = []; // 成功的回调函数 集合
        this.onRejectedCallbacks = []; // 失败的回调函数 集合
        let resolve = (value) => {
            if (this.status === PENDING) {
                this.value = value;
                this.status = RESOLVE;
                console.log(this.onResolvedCallbacks)
                this.onResolvedCallbacks.forEach(fn => fn());
            }

        } // 不属于实例上的 是单独每个人都有的
        let reject = (reason) => {
            if (this.status === PENDING) {
                this.reason = reason;
                this.status = REJECT;
                console.log(this.onRejectedCallbacks)
                this.onRejectedCallbacks.forEach(fn => fn());
            }

        }
        // promise 发生了错误的逻辑也会 执行 失败
        try {
            executor(resolve, reject); // 这个是执行器 默认立即执行
        } catch (e) {
            console.log(e)
            reject(e);
        }
    }

    // 1.promise 的 成功或失败的回调的 返回值 可以传递到外层的 then
    // 2. 如果返回值为普通值 可以当下一个回调 then 的参数 可能有 promise 的情况(采用 promis的状态 判断下一次的 成功或者失败) 还有 error的情况 出错就一点会走下一次的失败
    // 3. 错误处理 如果 自己没有错误处理 他会向下查找
    // 4. 每次执行完promise.then 方法后返回的都是一个 "promise"(promise 一旦成功或者失败就不能修改)


    then(onFulfiled, onRejected) {
        // console.log(1, this.onResolvedCallbacks)
        console.log(1, this.onRejectedCallbacks,this.status)
        onFulfiled = typeof onFulfiled === "function"? onFulfiled:v=>v;
        onRejected = typeof onRejected === "function"? onRejected:err=>{throw err};
        let promise2 = new Promise((resolve,reject)=>{ // 为了实现链式调用
            if (this.status === RESOLVE) {
                setTimeout(()=>{
                    try{
                        let x =   onFulfiled(this.value);
                        resolvePromise(promise2,x,resolve,reject);
                    }catch (e) {
                        reject(e);
                    }

                },0)


            }
            if (this.status === REJECT  ) {

                setTimeout(()=>{
                    try{
                        let x =  onRejected(this.reason);
                        resolvePromise(promise2,x,resolve,reject);
                    }catch (e) {
                        reject(e);
                    }

                },0)
            }
            if (this.status === PENDING) {

                this.onResolvedCallbacks.push(() => {

                    setTimeout(()=>{
                        try{
                            let x =  onFulfiled(this.value);
                            resolvePromise(promise2,x,resolve,reject);
                        }catch (e) {
                            reject(e);
                        }

                    },0)
                })
                this.onRejectedCallbacks.push(() => {

                    setTimeout(()=>{
                        try{
                            let x =  onRejected(this.reason);
                            resolvePromise(promise2,x,resolve,reject);
                        }catch (e) {
                            reject(e);
                        }

                    },0)
                })
            }
        })
        return promise2
    }
}

module.exports = Promise;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值