手写Promise源码

有理解不对的地方求指点,一起沟通交流。

思路

1、根据Promise最初的语法糖,创建MyPromise class类。

2、使用constructor 接受new MyPromise传入函数能立即执行。

3、执行resolve和reject:

​ 传入的函数中能执行resolve和reject ,是因为在new的时候传的函数有两个形参,这个函数接受两个形参只接受函数,你才能resolve() | reject(),可以name(‘df’)的都是方法,方法来源是在执行这个函数的时候,MyPromise 将成功和失败需要的方法传入给这个函数,让new MyPromise时传入的立即执行函数自行根据当前请求状态去调用。

​ 在执行resolve的时候,能在MyPromise 类中的 resolve方法能接受resolve传入的成功值,在执行resolve的时候能接受失败的原因。

4、在执行resolve和reject的时候,需要将将等待改成对应的状态,一旦改变当前承诺不能再变:

​ pending ==> fulfilled 等待 =》改成成功

​ pending ==> rejected 等待 =》改成失败

​ 由此,我需要记录当前承诺的状态

​ 不为等待的状态时,说明当前的状态已经改变,使用return结束当前函数,阻止执行。

5、Promise 有个then方法,可以接受两个参数,成功的回调函数和失败的回调函数,其实就是根据状态来调用的。

​ 其实就是跟上面记录的判断来坐处理,如果当前状态是成功,则调用then的第一个参数,失败则调用then的第二个参数。

|

|

上面5个步骤可以实现最基础的Promise基本功能

6、处理异步状态:

​ 当then不为成功和失败就等待的状态。

​ 将then的回调函数在等待的状态时存起来,在resolve或者reject时执行调用then的回调函数。

7、链式调用 (主要关注两点)

​ 第一:在then执行的时候返回 MyPromise 对象实现链式调用;

​ 第二:在then中的三个状态的执行放到返回的MyPromise对象中,使用resolve或reject接受回调函数的返回值做为参数作为下个then的参数。

8、then链式调用返回Promise

​ 对then 传入的回调执行返回值做个判断,如果返回值是 MyPromise 则对值使用.then进行处理,如果是普通值,则直接resolve.

​ 使用 instanceof 来判断。

9、then 链式调用返回自身照常循环调用

​ 使用then执行返回new MyPromise 的时候用变量接受,这个变量跟then返回的值进行 === 对比,如果一样说明对象的引用地址是一样,是同一个对象,调用reject(new Error()) 抛出错误。

​ 正常肯定是比不了的,因为new MyPromise时的变量是在new执行后才能拿到的结果,而判断是在new 执行中;

​ 使用setTimeout 将判断包裹起来,不是为定时执行,是为了将代码变成异步代码。

10、MyPromise 异常处理

​ 在MyPromise 的 constructor 中使用try catch包裹传入的执行函数,将代码放到try catch中监听错误,异常则调用reject。

​ 在then的成功和失败的状态执行时,使用try catch将成功和失败要执行的代码块包裹起来,异常则调用reject。

11、then可选参数处理

​ 当then接受的实参不是 函数的时候使用,当前形参的值为 val => val,then失败的参数不为函数时,则在返回的函数中抛出异常 err => {throw err}

12、实现all功能的实现

​ 从promise的语法中可以得出最基本的几点:

​ 能通过Promise.all,可以证明它是静态方法。

​ 能同时处理几个请求和接受的参数上看,all只接受数组,可以通instanceof 准确判断数组

​ (instanceof优点可以判断引用类型不能准确判断基本数据类型)

​ 所有的请求为真则为真,一个请求为假返回失败的值。

​ 所以:

​ 创建一个静态的方法;

​ 对接受值做判断处理:

​ 创建一个数组存放all返回的值;

​ 接受的值必须是数组,不为数组抛出错误;

​ 如果接受的值是空数组,则返回空数组;

​ 如果接受的是没有包含异步的请求的数组,执行循环遍历,碰到有异步的原生,则.then进行解析它,为真时往数组push,为失败则停止调用,然后返回失败值,不管前面多少个成功,都返回失败。

​ 当异步成功执行完毕,判断当前push后的数组长度是否跟传入的all数组的长度一样,一样说明所有异步执行完毕了

13、Promise.resolve和Promise.reject 功能的实现:

​ 语法可以看出这两个方法都是静态方法。

​ 它们都是返回Promise。

​ 根据静态方法调用对应的状态。

14、实现finally方法

​ 不管成功还是失败都能调用这个finally方法。

​ 只接受函数作为参数。返回MyPromise对象。

​ 从只能通过new 返回的变量才调用可以看出是原型方法不是静态方法。

15、catch的功能

​ 只接受失败的回调函数,成功的回调函数无需传入函数。

创建Promise 类

Promise代码

从 new Promise()可以看出,Promise是一个构造函数对象

MyPromise代码

class MyPromise()

传入函数 能立即执行

Promise代码

从promise的使用中可以发现,Promise的参数是一个函数,而且函数体是立即执行的,我们也需要传入一个函数进来,并且带了resolve和reject的形参函数

new Promise((resolve, reject) => {

})

MyPromise 代码

在new Promise 时,传入一个函数,使用constructor接受这个这个函数, 来做立即执行

//通过打应111,我们可以得出,通过使用constructor构造器立即执行传过来的函数
class MyPromise{
	constructor(execute){ //这个execute接受的值就是new MyPromise 中从中传的函数
		console.log(execute) //(resolve, jeject) => {console.log(111)}
        execute();//打印111  
	}
}
new MyPromise((resolve, reject) => {
 console.log(111)
})

执行resolve和reject

Promise 代码

参考Promise 语法中看resolve()和reject(),可以得出它们都是一个函数,能传参立即执行

new Promise((resolve, reject) => {
    resolve('成功了')
})

MyPromise 代码

核心:resolve和reject是在传入MyPromise执行的,在new Promise()的时候 传入的函数接受两个函数作为参数,函数的来源在MyPromise的内部定义了resolve,和reject两个方法,在请求结果下来的时候调用。

class MyPromise{
    constructor(execute){
        // execute() //会让调用的resolve报错 resolve is not a function
        
        execute(value => {
            //正常打印,不会报错,说明是将MyPromise的代码拿到new MyPromise里去执行,我们就可以定义两个语义化的函数名称,入下面的优化效果代码
            // console.log("我来验证猜想"); 
            //既然没错,尝试传参
            console.log(value); //打印 成功了,拿到了resolve传入的值
        })
    }
}
const myProm = new MyPromise((resolve, reject) => {
    console.log(111)
    /**
     * 1、resolve所在的函数传入到了constructor构造器里,而且resolve和reject是通过传参传进的函数。
     * 2、执行的时候没传参数当然就啥都没有,等于undefined(),当然报错,传入参数验证猜想
     * 3、经过接受到的值,可以确定execute在执行的时候要传入两个方法,可以在MyPromise中实现两个实例方法
     */
    resolve("成功了")
    console.log(reject)
})

优化效果

class MyPromise{
    constructor(execute){
        //execute(resolve, reject); //resolve is not defined 还是报错,为什么嘞,class里调用需要this 
        execute(this.resolve, this.reject) 
    }
    resolve = res => { 
        console.log(res)
    }
    reject = error => {
        console.log(error)
    }
}
new MyPromise((resolve, reject) => {  //promise的状态一旦改变不能再变不能输出成功又输出失败
    resolve('成功了') //正常打印成功的值 成功了
    reject('失败了') //正常打印失败原因 失败了
})

承诺状态改变不能再变

Promise 代码

Promise 代码,只输出1,不管执行多少遍resolve都是只执行一遍,reject也是一样。

const prom = new Promise((resolve, reject) => {
	resolve('成功') 
	resolve('成功')
	reject('失败')
})
prom.then(val=> {
    console.log(1) 
},err=> {
    console.log(err)
})

MyPromise 代码

核心:其实就是定义三个状态:分别为等待、成功和失败,当当前状态为等待的情况下,根据new立即执行函数的调用,执行后将状态改变,不为等待的状态去执行,直接return 结束。

//为不执行两遍、重复执行。
//只能从等待改成成功,等待改成失败,那就需要一个记录当前的状态
//录,有三个状态
const pendind = 'PENDING'; //等待
const fulfilled = 'FULFILLED'; // 成功
const rejected = 'REJECTED'; //失败
class MyPromise{
    status = 'PENDING' //默认状态为等待状态
    constructor(execute){
        execute(this.resolve, this.reject)
    }
    
    resolve = res => {
        //不为等待状态return,说明状态一改不能再改
        if(this.status !== pendind) return; //不是等待状态不让执行
        
        this.status = fulfilled; //在等待状态下将等待状态改成成功状态
        
        console.log(res)
    }
    reject = err => {
        //不为等待状态return,说明状态一改不能再改
        if(this.status !== pendind) return; //不是等待状态不让执行
      
        this.status = rejected; //在等待状态下将等待状态改成失败状态
        
        console.log(err);
    }
    
    
}
new MyPromise((resolve, reject) => {
    resolve('成功了');
    resolve('成功了');
    reject('失败了')
})

then实现回调

Promise代码

const prom = new Promise((resolve, reject) => {
    resolve('成功了');
    reject('失败了')
})
//根据成功状态调用对应回调函数
prom.then(res => {
    console.log(res)
}, err => {
    console.log(err)
})

MyPromise 实现

核心:就是在MyPromise 中定义了then方法,在then方法中根据当前MyPromise的状态决定是调用then的第一个方法还是第二个方法,将成功或者失败的值传递给这个then的回调函数。。

//定义三个状态 
const pending = 'PENDING'; //定义等待的状态
const fulfilled = 'FULFILLED'; //定义成功的状态
const rejected = 'REJECTED'; //定义失败的状态
class MyPromise{
    status = pending; //默认状态为等待
	successValue = undefined; //用于记录成功的值
	failureError = undefined; //用于记录失败的原因

    constructor(execute){
        execute(this.resolve, this.reject)
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successValue = res; //将成功的值记录
        console.log(res)
    }
    reject = error => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.failureError = error;
		console.log(error)
    }
    then = (success, failure) => {
        //console.log('调用then方法了'); //(1、)测试成功
        
        //两个都打印了肯定不对,只能打印一个,而且得根据当前的状态来判断调用哪个(2、)
        //success('then调用成功的回调函数咯')
        //failure('then调用失败的回调函数咯')
        
        //根据定义的status的状态来调用,但是会输出undefined,需要成功的值和失败的原因传进来
        //if(this.status == fulfilled) success(); //会输出 undefined
        //if(this.status == rejected) failure(); //会输出undefined
        
        //在上面调用resolve的时候记录成功的值,在调用reject的时候记录失败的原因,作为这里的函数实参
        //if(this.status === fulfilled) success(this.successValue);
        //if(this.status === rejected) failure(this.failureError);
        
        //改下可读性
        if(this.status === fulfilled) { //成功状态的时候执行,【用于处理同步代码】
            success(this.successValue);
        }else if(this.status === rejected) { //失败后的执行,【用于处理同步的代码】
            failure(this.failureError);     
        }
    }
}
const MyProm = new MyPromise((resolve, reject) => { //定义了就不会报then 不是方法的错误了
    //resolve('成功了,传入值');
    //reject('失败了,传入失败原因');
    reject(new Error('参数错误'));
    
    //setTimeout(() => {
    //	reject(new Error('参数错误'));
    //}, 1000)
})
//MyProm.then() //MyProm.then is not a function 需要在里面定义一个then方法
MyProm.then(res => {
    console.log("then的成功回调值", res); 
}, err => {
    console.log("then的失败回调值", err);
})

缺点:虽然基本版本的promise实现了,但是你会发现这段代码使用setTimeout 的时候, then 根本没有执行,直白的说的异步代码根本没啥效果,在异步(setTimeout)的时候不执行,在同步的时候(没有加setTimeout)却可以。看下面的代码解决这个问题


处理异步状态

Promise 代码

Promise 模拟实现异步代码

const prom = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功了')
    }, 1000)
})
prom.then(res => {
    console.log(res)
}, error => {
    console.log(error)
})

MyPromise 实现

通过setTimeout模拟异步等待接口

核心:通过在等待的状态时,将then的函数存起来,等在调用resolve或者reject的时候调用回调函数来实现这个功能。

const pinding = 'PENDING'; //等待的状态
const fulfilled = 'FULFILLED'; //成功的状态
const rejected = 'REJECTED'; //失败的状态
class MyPromise{
    status = pinding;
	successValue = undefined;
	failureError = undefined;

	successCallBack = undefined; //将then 成功的回调函数存存起来 
	failCallback = undefined; // 将then 失败的回调函数存起立

    constructor(execute){
        execute(this.resolve, this.reject)
    }
    resolve = res => { 
        if(this.status !== pinding) return;//只有等待状态才能改变
        this.status = fulfilled;//用于将等待状态改变成成功状态
        this.successValue = res;
        this.successCallBack && this.successCallBack(res) // 在等待状态的时候,异步代码结束后调用resolve函数的时候,执行then的回调函数
    }
    reject = error => {
        if(this.status !== pinding) return;//只有等待状态才能改变
        this.status = rejected;//用于将等待状态改变成失败状态
        this.failureError = error;
        this.failCallback && this.failCallback(error) // 在等待状态的时候,异步代码结束后调用reject函数的时候,执行then的回调函数
    }
    then = (success, failure) => {
        //根据状态来调用
        if(this.status === fulfilled){
           success(this.successValue);
        } else if(this.status === rejected) {
            failure(this.failureError);
        } else { //在上面的基础我们需要对等待的状态进行处理,如果是等待状态,我们需要将then的函数存起来【不为成功和失败,说明当前状态为等待,也就是处理异步代码】
            this.sucssessCallBark = success; //在等待的状态时,将then的成功回调函数缓存起来
            this.failCallback = failure; //在等待的状态时,将then的失败回调函数缓存起来
        }
    }
}
const prom = new MyPromise((resolve, reject) => { 
    setTimeout(() => {
        reject(new Error('失败了'))
    }, 1000)
    
    setTimeout(() => {
        resolve('成功了')
    }, 1000)
})

prom.then(res => { 
    console.log("then",res) 
}, error => {
    console.log('error',error)
})

确定:但是上面的代码却不能将一个promise返回对象 多次调用。

多次调用then

一个Promise 返回的promise对象是可以同时被多个then调用的

Promise 代码

promise 代码,多个then的时候能同时打印,而我们MyPromise却不行,只能执行一次

const prom = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功了')
    }, 2000)
})
prom.then(res => { 
    console.log(1,res)
},error => {
    console.log(error)
})
prom.then(res => {
    console.log(2,res)
},error => {
    console.log(error)
})
prom.then(res => {
    console.log(3,res)
},error => {
    console.log(error)
})

MyPromise 代码

MyPromise 实现同一个promise对象可以同时调用

核心是:在异步等待的状态时,分别将成功的和失败的回调函数push在数组中,分别在成功或者失败的时候调用各自的回调函数列表,达到异步的效果,其实就是使用数组去循环执行回调函数列表的

const pending = "PENDING"; // 等待状态
const fulfilled = 'FULFILLED'; // 成功状态
const rejected = 'REJECTED'; // 失败状态
class MyPromise{
    status = pending; 
	successValue = undefined;
	fulfilError = undefined;
 	//将缓存then的属性值改成数组,才能存多个回调函数	
	successCallBark = [];
	//将缓存then的属性值改成数组,才能存多个回调函数	
	fulfilCallBark = [];

    constructor(execute){
        execute(this.resolve, this.reject)
    }
    resolve = res => {
        if(this.status !== pending) return;
       	this.status = fulfilled;
        this.successValue = res;
        //this.successCallBack && this.successCallBack(res); //改了数组就不能这样写了
        //得用循环来实现
        while(this.successCallBark.length){ //存储的回调函数数组不为空的时候才执行
            //shift没次从数组中取出第一个回调函数去执行,知道最后一个被取出执行,循环结束
            this.successCallBark.shift()(res);
        }
    }
    reject = error => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.fulfilError = error;
        //is.failCallback && this.failCallback(error); // //改了数组就不能这样写了
        //跟成功的逻辑是一个,只不过是简写的方式
        while(this.fulfilCallBark.length) this.fulfilCallBark.shift()(error)
    }
    then = (succerrCallBark, failureCallBark) => {
        if(this.status === fulfilled) { //处理同步代码 
            succerrCallBark(this.successValue)
        } else if(this.status === rejected) { //处理同步代码
			failureCallBark(this.fulfilError)
        } else { //对异步等待状态代码进行缓存等待执行
            //对异步代码做处理,你要等待或者执行多个回调函数就需要数组,将上面存储函数的undefined改成数组
            this.successCallBark.push(succerrCallBark)
            this.fulfilCallBark.push(failureCallBark)
        }
    }
}

const prom = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功了')
    }, 1000)
})

prom.then(res => {
    console.log('res1', res)
}, error => {
    console.log('err1',error)
})

prom.then(res => {
    console.log('res2', res)
}, error => {
    console.log('err2',error)
})
prom.then(res => {
    console.log('res3', res)
}, error => {
    console.log('err3',error)
})

但是上面的代码又不支持then链式调用。

then链式调用

需要能返回then和能接上一个then的值

Promise代码

const prom = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(111)
    })
})
prom.then((res) => {
    console.log(res)
    return res;
}).then(value => {
    console.log(value)
})

MyPromise代码

核心:then能链式调用需要返回MyPromise对象;then能接受到上一个then的返回值用resolve(将值传给下个then),这个值就说then回调函数的执行的返回值。

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successValue = undefined;
	rejectError = undefined;
	fulfillCall = [];
	rejectCall = [];

    constructor(execute){
        console.log(execute)
        execute(this.resolve, this.reject)
    }
    resolve =  res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successValue = res;
        while(this.fulfillCall.length) {
            let he = this.fulfillCall.shift()(res);
        }
    }
    reject = err => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectError = err;
        while(this.rejectCall.length) this.rejectCall.shift()(err);
    }
    then = (fulfilledCallBark, rejectCallBark) => {
        // if(this.status === fulfilled) {
        //     console.log(this.status)
        //     fulfilledCallBark(this.successValue)
        // } else if(this.status === rejected) {
        //     rejectCallBark(this.rejectError)
        // } else {
        //     this.fulfillCall.push(fulfilledCallBark);
        //     this.rejectCall.push(rejectCallBark)
        // }
       
        // 只是 return new MyPromise()  就会报这个错误,因为这个then里return的MyPromise,既然是new Promise就得传立即执行函数呀,但是上面的代码不支持异步
        //return new MyPromise() //execute is not a function
        
        
        //发现fulfilledCallBark 执行的返回值其实就是then的返回值
        return new MyPromise((resolve, reject) => { //MyPromise 的这个函数是立即执行的,里面的判断也是立即执行的,直接放到MyPromise里面
            
            if(this.status === fulfilled) {
                const val = fulfilledCallBark(this.successValue)
                resolve(val)
            } else if(this.status === rejected) {
                rejectCallBark(this.rejectError)
            } else {
                this.fulfillCall.push(fulfilledCallBark);
                this.rejectCall.push(rejectCallBark)
            }
        })
        
    }
}
const prom = new MyPromise((resolve, reject) => {
    resolve(121)
    //reject(new Error('失败了'))
})
const th = prom.then(res => {
    console.log('then 成功', res)
    return res;
}, err => {
    console.log('then 失败', err)
}).then(val => {
    console.log("then2成功",val)
})

then链式调用返回Promise对象

其实就是then返回普通值和返回promise做处理,如果是普通值通过resolve将值传给下个then,如果是MyPromise 则进行出现然后再返回给下个then。

Promise

const prom = new Promise((resolve,reject) => {
	resolve('成功了')
})
prom.then(res => {
	console.log('then1',res)
	return new Promise((resolve, reject) => {
		resolve('he') //then1 成功了
	})
}).then(res => {
	console.log('then2', res) //then2 he
})

MyPromise

核心:就是对then的回调函数执行的返回值使用 x instanceof MyPromise做判断,如果是MyPromise对象,则对对象进行处理,如果是普通值直接resolve;

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successVal = undefined;
	rejectErr = undefined;
	successCall = [];
	rejectCall = [];

    constructor(execute){
        execute(this.resolve, this.reject)
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successVal = res;
    }
    reject = err => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectErr = err;
    }
    then = (fulfilledCallBark, rejectedCallBark) => {
        const prom = new MyPromise((resolve, reject) => {
            if(this.status == fulfilled){
                const val = fulfilledCallBark(this.successVal);
                this.resolvePromise(val, resolve, reject);
            } else if(this.status == rejected) {
                rejectedCallBark(this.rejectErr)
            } else {
                this.successCall.push(fulfilledCallBark);
                this.rejectCall.push(rejectedCallBark);
            }		
        })
        return prom;
    }
    //通过resolve方法进行判断解析
    resolvePromise = (x, resolve, reject) => {
        if(x instanceof MyPromise) {
            //Promise对象
            //x.then(res => resolve(res), err => reject(err))
            //x.then(resolve, reject);
        }else {
            resolve(x);
        }
    }
}

const prom = new MyPromise((resolve, reject) => {
    resolve('成功了')
    reject('失败了')
})
prom.then(res => {
    console.log("then1", res);
    return new MyPromise((resolve, reject) => {
        resolve('he');
    })
}).then(res => {
    console.log('then2', res)
})

处理then返回自身

当Promise 在then返回的时候返回then自己,照成了循环调用问题。

Promise

const prom = new Promise((resolve, reject) => {
    resolve('成功了')
})
const pr = prom.then((res) => {
    console.log(res); // 成功了
    return pr; //Uncaught (in promise) TypeError: Chaining cycle detected for promise #<Promise>
})
pr.then(res => {},err => {
    console.log(err.message) //Chaining cycle detected for promise #<Promise>
})

MyPomise

核心:将链式调用创建new MyPromise() 跟then回调函数执行返回MyPromise 进行对比,全等 说明对象的引用是同一个,是同一个对象,就return 阻止 程序继续执行,并抛出异常;new MyPromise() 的执行里面要拿到本身new的结果, 使用setTimeout将代码改成异步代码才能拿到new 的值 ,进行对比

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successVal = undefined;
	rejectErr = undefined;
	successCall = [];
	rejectCall = [];

    constructor(execute){
        execute(this.resolve, this.reject)
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successVal = res;
        while(this.successCall.length) this.successCall.shift()(res)
    }
    reject = err => {
        console.log(this.status)
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectErr = err;
       	while(this.rejectCall.length) this.rejectCall.shift()(err)
    }
    then = (fulfilledCallBark, rejectedCallBark) => {
        const promise2 = new MyPromise((resolve, reject) => {
            if(this.status == fulfilled){
                //这里加定时不是为了延迟,而是让这段代码成为异步代码
                //在这里想拿到promise2是new MyPromise执行结束后才能拿到,而这里是执行的时候拿是拿不到的,需要将这段代码改成异步代码
                setTimeout(() => {  
                    const value = fulfilledCallBark(this.successVal);
                	this.resolvePromise(promise2, value, resolve, reject);
                },0)
            } else if(this.status == rejected) {
                rejectedCallBark(this.rejectErr)
            } else {
                this.successCall.push(fulfilledCallBark);
                this.rejectCall.push(rejectedCallBark);
            }		
        })
        return promise2;
    }
    //通过resolve方法进行判断解析
    resolvePromise = (promise2, x, resolve, reject) => {
        console.log(promise2 === x)
        if(promise2 === x){
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
        console.log('执行了')
        if(x instanceof MyPromise) {
            //Promise对象
            //x.then(res => resolve(res), err => reject(err))
            x.then(resolve, reject);
        }else {
            resolve(x);
        }
    }
}

const prom = new MyPromise((resolve, reject) => {
    resolve('成功了')
    reject('失败了')
})
const pr = prom.then(res => {
    console.log("then1", res);
    return pr;
})
pr.then(res => { //能连续执行肯定是push,然后在成功和失败的结果下来了调用then的回调函数。
    console.log("then2 res",res)
},err => {
    console.log("then2Err",err.message)
})

Promise 异常处理

new Promise 立即执行函数异常

Promise

const prom = new Promise((resolve, reject) => {
    throw new Error('函数错误了')
})
prom.then((res) => {
    console.log(res)
}, err => {
    console.log(err)
})

MyPromise

核心:就是在立即执行的 constructor 构造函数中 加入 try catch 处理,报错调用reject(e) ,e就是catch中抛出的异常

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successVal = undefined;
	rejectErr = undefined;
	successCall = [];
	rejectCall = [];

    constructor(execute){
        try{
            execute(this.resolve, this.reject)
        } catch(e)  {
          return this.reject(e)   
        }
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successVal = res;
        while(this.successCall.length) this.successCall.shift()(res)
    }
    reject = err => {
        console.log(this.status)
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectErr = err;
       	while(this.rejectCall.length) this.rejectCall.shift()(err)
    }
    then = (fulfilledCallBark, rejectedCallBark) => {
        const promise2 = new MyPromise((resolve, reject) => {
            if(this.status == fulfilled){
                //这里加定时不是为了延迟,而是让这段代码成为异步代码
                //在这里想拿到promise2是new MyPromise执行结束后才能拿到,而这里是执行的时候拿是拿不到的,需要将这段代码改成异步代码
                setTimeout(() => {  
                    const value = fulfilledCallBark(this.successVal);
                	this.resolvePromise(promise2, value, resolve, reject);
                },0)
            } else if(this.status == rejected) {
                setTimeout(() => {
                    const errVal = rejectedCallBark(this.rejectErr);
                    this.resolvePromise(promise2, errVal, resolve, reject);
                }, 0)
            } else {
                this.successCall.push(fulfilledCallBark);
                this.rejectCall.push(rejectedCallBark);
            }		
        })
        return promise2;
    }
    //通过resolve方法进行判断解析
    resolvePromise = (promise2, x, resolve, reject) => {
        if(promise2 === x){
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
        if(x instanceof MyPromise) {
            //Promise对象
            //x.then(res => resolve(res), err => reject(err))
            x.then(resolve, reject);
        }else {
            resolve(x);
        }
    }
}

const prom = new MyPromise((resolve, reject) => {
    throw new Error('错误啦')
    resolve('成功了')
    reject('失败了')
})
const pr = prom.then(res => {
    console.log("then1 res", res);
    return pr;
}, err => {
    console.log("then1 err",err)
})

then 回调函数执行异常

Promise

const prom = new Promise((resolve, reject) => {
    resolve('成功了')
})
prom.then(res => {
    console.log("then1 res", res)
	throw new Error('then1 错误了');
}, err => {
    console.log("then1 err",err);
}).then(res => {
    console.log("then2 res", res)
}, err => {
    console.log("then2 err",err);
})

MyPromise

不管是成功还是失败的回调函数在执行的时候发生错误,使用try catch包裹监听错误,使用setTimeout将代码包裹,使得代码成为异步代码,在代码异常的时候reject(trycatch的异常)

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successVal = undefined;
	rejectErr = undefined;
	successCall = [];
	rejectCall = [];

    constructor(execute){
        try{
            execute(this.resolve, this.reject)
        } catch(e)  {
          return this.reject(e)   
        }
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successVal = res;
        while(this.successCall.length) this.successCall.shift()(res)
    }
    reject = err => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectErr = err;
        while(this.rejectCall.length) this.rejectCall.shift()(err)
    }
    then = (fulfilledCallBark, rejectedCallBark) => {
        const promise2 = new MyPromise((resolve, reject) => {
            if(this.status == fulfilled){
                //这里加定时不是为了延迟,而是让这段代码成为异步代码
                //在这里想拿到promise2是new MyPromise执行结束后才能拿到,而这里是执行的时候拿是拿不到的,需要将这段代码改成异步代码
                setTimeout(() => {  
                    //如果then的回调函数中抛出异常,则在成功状态下添加try catch进行异常处理,异常reject(e) e则是执行then中成功回调函数时出现的错误
                    try{
                    	const value = fulfilledCallBark(this.successVal);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
            			reject(e)
        		   }
                },0)
            } else if(this.status == rejected) {
                setTimeout(() => {
                    // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                    try{
                    	const value = rejectedCallBark(this.rejectErr);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
                        reject(e)
        		   }
                }, 0)
            } else {
                this.successCall.push(fulfilledCallBark);
                this.rejectCall.push(rejectedCallBark);
            }		
        })
        return promise2;
    }
    //通过resolve方法进行判断解析
    resolvePromise = (promise2, x, resolve, reject) => {
        if(promise2 === x){
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
        if(x instanceof MyPromise) {
            //Promise对象
            //x.then(res => resolve(res), err => reject(err))
            x.then(resolve, reject);
        }else {
            resolve(x);
        }
    }
}

const prom = new MyPromise((resolve, reject) => {
    reject('失败了')
    resolve('成功了')
})

prom.then(res => {
    console.log("then1 res----", res)
	//throw new Error('then1 错误了');
}, err => {
    console.log("then1 err",err);
    throw new Error('then1 出现错误了');
}).then(res => {
    console.log("then2 res", res)
}, err => {
    console.log("then2 err",err);
})

then异步链式调用

MyPromise

核心是在等待的状态时,将回调函数列表push 箭头函数,当调用resolve或者reject的时候调用执行对应的函数,执行函数的定时器,异步执行

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successVal = undefined;
	rejectErr = undefined;
	successCall = [];
	rejectCall = [];

    constructor(execute){
        try{
            execute(this.resolve, this.reject)
        } catch(e)  {
          return this.reject(e)   
        }
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successVal = res;
        //then 链式异步调用的时候,不需要传参
        while(this.successCall.length) this.successCall.shift()()
    }
    reject = err => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectErr = err;
        //then 链式异步调用的时候,不需要传参
        while(this.rejectCall.length) this.rejectCall.shift()()
    }
    then = (fulfilledCallBark, rejectedCallBark) => {
        const promise2 = new MyPromise((resolve, reject) => {
            if(this.status == fulfilled){
                //这里加定时不是为了延迟,而是让这段代码成为异步代码
                //在这里想拿到promise2是new MyPromise执行结束后才能拿到,而这里是执行的时候拿是拿不到的,需要将这段代码改成异步代码
                setTimeout(() => {  
                    //如果then的回调函数中抛出异常,则在成功状态下添加try catch进行异常处理,异常reject(e) e则是执行then中成功回调函数时出现的错误
                    try{
                    	const value = fulfilledCallBark(this.successVal);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
            			reject(e)
        		   }
                },0)
            } else if(this.status == rejected) {
                setTimeout(() => {
                    // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                    try{
                    	const value = rejectedCallBark(this.rejectErr);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
                        reject(e)
        		   }
                }, 0)
            } else {
                this.successCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = fulfilledCallBark(this.successVal);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                    
                });
                this.rejectCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = rejectedCallBark(this.rejectErr);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                });
            }		
        })
        return promise2;
    }
    //通过resolve方法进行判断解析
    resolvePromise = (promise2, x, resolve, reject) => {
        if(promise2 === x){
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
        if(x instanceof MyPromise) {
            //Promise对象
            //x.then(res => resolve(res), err => reject(err))
            x.then(resolve, reject);
        }else {
            resolve(x);
        }
    }
}

const prom = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        reject('失败了')
    }, 2000)
    
    // resolve('成功了')
})

prom.then(res => {
    console.log("then1 res----", res)
	//throw new Error('then1 错误了');
}, err => {
    console.log("then1 err",err);
    // throw new Error('then1 出现错误了');
    return 'then err 返回错误'
}).then(res => {
    console.log("then2 res", res)
}, err => {
    console.log("then2 err",err);
})

then 可选参数处理

Promise

核心:then() 里面的实参必须是函数,不是函数都无视它,包括对象,promise 的对象无视它,它们都会被替换为 val => val,所以它们等价于 prom.then(1).then(val => val).then(val => val).then(res => console.log(res))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s8EROlEz-1626512257982)(C:\Users\TOM\Desktop\1609986899iH4e4F.png)]

const prom = new Promise((resolve, reject) => {
    resolve('成功了')
})
prom.then(1).then(Promise.resolve(2)).then(res => console.log(res))

MyPromise

核心:只有then没传参或者实参不是函数,统统替换成val => val,使用typeof可以准确判断函数类型。

typeof虽然能准确判断基本类型,但是null 是基本类型,是js的bug,但typeof判断引用类型不准确,唯独function这个对象可以准确判断。

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successVal = undefined;
	rejectErr = undefined;
	successCall = [];
	rejectCall = [];

    constructor(execute){
        try{
            execute(this.resolve, this.reject)
        } catch(e)  {
          return this.reject(e)   
        }
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successVal = res;
        //then 链式异步调用的时候,不需要传参
        while(this.successCall.length) this.successCall.shift()()
    }
    reject = err => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectErr = err;
        //then 链式异步调用的时候,不需要传参
        while(this.rejectCall.length) this.rejectCall.shift()()
    }
    then = (fulfilledCallBark, rejectedCallBark) => {
        //只要不是函数,都无视它,替换成val => val
        fulfilledCallBark = (fulfilledCallBark && typeof(fulfilledCallBark) === "function") ? fulfilledCallBark : val => val;
        rejectedCallBark = (rejectedCallBark && typeof(rejectedCallBark) === "function") ? rejectedCallBark : err => {throw err};

        const promise2 = new MyPromise((resolve, reject) => {
            if(this.status == fulfilled){
                //这里加定时不是为了延迟,而是让这段代码成为异步代码
                //在这里想拿到promise2是new MyPromise执行结束后才能拿到,而这里是执行的时候拿是拿不到的,需要将这段代码改成异步代码
                setTimeout(() => {  
                    //如果then的回调函数中抛出异常,则在成功状态下添加try catch进行异常处理,异常reject(e) e则是执行then中成功回调函数时出现的错误
                    try{
                    	const value = fulfilledCallBark(this.successVal);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
            			reject(e)
        		   }
                },0)
            } else if(this.status == rejected) {
                setTimeout(() => {
                    // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                    try{
                    	const value = rejectedCallBark(this.rejectErr);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
                        reject(e)
        		   }
                }, 0)
            } else {
                this.successCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = fulfilledCallBark(this.successVal);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                    
                });
                this.rejectCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = rejectedCallBark(this.rejectErr);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                });
            }		
        })
        return promise2;
    }
    //通过resolve方法进行判断解析
    resolvePromise = (promise2, x, resolve, reject) => {
        if(promise2 === x){
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
        if(x instanceof MyPromise) {
            //Promise对象
            //x.then(res => resolve(res), err => reject(err))
            x.then(resolve, reject); 
        }else {
            resolve(x);
        }
    }
}

const prom = new MyPromise((resolve, reject) => {
    // setTimeout(() => {
    //     reject('失败了')
    // }, 2000)
    
    resolve('成功了')
})

prom.then(1).then(Promise.resolve(2)).then().then(Promise.resolve(1)).then(res => console.log('连续then',res), err => {console.log(err)})

promise.all 功能的实现

Promise

function fun1 () {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('成功了')
        }, 1000)
    })
}
function fun2 () {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('成功了')
        }, 2200)
    })
}
function fun3() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('失败了')
        }, 1200)
    })
}
Promise.all([fun2(), fun2(), fun3()]).then(res => {
    console.log(res)
}, err => {
    console.log(err)
})

MyPromise

核心:

1、从Promise.all([]).then() 中可以看出,all是一个静态方法,值只能接受数组类型,返回promise 接受处理的值,所有的为真才调用成功回调,一个失败则结束调用失败回调。

2、接受空数组返回空数组。

3、当前数组的不是MyPromise的时,往结果值push,如果是MyPromise对象,则使用then获取该Promise的值,根据状态来操作,成功则往结果数组push值,结果值长度是否传入值的长度是否一致,一致说明all的同步和异步执行完毕了,否则没有继续等待下个异步,如果是失败的promise,直接结束,因为一个失败后面异步怎么成功也是没有用的。

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successVal = undefined;
	rejectErr = undefined;
	successCall = [];
	rejectCall = [];

    constructor(execute){
        try{
            execute(this.resolve, this.reject)
        } catch(e)  {
          return this.reject(e)   
        }
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successVal = res;
        //then 链式异步调用的时候,不需要传参
        while(this.successCall.length) this.successCall.shift()()
    }
    reject = err => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectErr = err;
        //then 链式异步调用的时候,不需要传参
        while(this.rejectCall.length) this.rejectCall.shift()()
    }
    then = (fulfilledCallBark, rejectedCallBark) => {
        //只有不是函数,都无视它,替换成val => val
        fulfilledCallBark = (fulfilledCallBark && typeof(fulfilledCallBark) === "function") ? fulfilledCallBark : val => val;
        rejectedCallBark = (rejectedCallBark && typeof(rejectedCallBark) === "function") ? rejectedCallBark : err => {throw err};

        const promise2 = new MyPromise((resolve, reject) => {
            if(this.status == fulfilled){
                //这里加定时不是为了延迟,而是让这段代码成为异步代码
                //在这里想拿到promise2是new MyPromise执行结束后才能拿到,而这里是执行的时候拿是拿不到的,需要将这段代码改成异步代码
                setTimeout(() => {  
                    //如果then的回调函数中抛出异常,则在成功状态下添加try catch进行异常处理,异常reject(e) e则是执行then中成功回调函数时出现的错误
                    try{
                    	const value = fulfilledCallBark(this.successVal);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
            			reject(e)
        		   }
                },0)
            } else if(this.status == rejected) {
                setTimeout(() => {
                    // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                    try{
                    	const value = rejectedCallBark(this.rejectErr);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
                        reject(e)
        		   }
                }, 0)
            } else {
                this.successCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = fulfilledCallBark(this.successVal);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                    
                });
                this.rejectCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = rejectedCallBark(this.rejectErr);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                });
            }		
        })
        return promise2;
    }
    //实现all 的方法
    static all (arr) {
        if(arr instanceof Array) {
            if(arr.length === 0) return arr;
            const resultArr = [];
            const arrLen = arr.length;
            const prom = new Promise((resolve, reject) => {
                while(arr.length) {
                    const current = arr.shift();
                    if(current instanceof MyPromise){
                        current.then(res => {
                            resultArr.push(res);
                            if(arrLen == resultArr.length) {
                                resolve(resultArr)
                            }
                        }, err => {
                            reject(err);
                            return err;
                        })
                    } else {
                        resultArr.push(current);
                    }
                }
            })
            return prom;
        }else {
            throw new Error(`${typeof(arr)} is not iterable (cannot read property Symbol(Symbol.iterator))`)
        }
    }


    //通过resolve方法进行判断解析
    resolvePromise = (promise2, x, resolve, reject) => {
        if(promise2 === x){
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
        if(x instanceof MyPromise) {
            //Promise对象
            //x.then(res => resolve(res), err => reject(err))
            x.then(resolve, reject); 
        }else {
            resolve(x);
        }
    }
}

const prom = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        reject('失败了1 异步')
    }, 4000)
    
    // resolve('成功了1 同步')
})
const prom2 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功了2 异步')
    }, 4000)
    // reject('失败了2 同步')
})
const prom3 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        reject('失败了3 异步')
    }, 4000)
    
    // resolve('成功了3 同步')
})
const prom4 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功了4 同步')
    }, 9000)
})

function fun(){}
MyPromise.all([1, [], {}, fun, '11', prom, prom2, prom3, prom4]).then(res => {
    console.log("成功了",res)
}, err => {
    console.log("失败了",err)
})

Primise.resolve 功能的实现

Promise

Promise.resolve(1).then().then(console.log, console.log)

MyPromise

核心:

resolve是静态方法;

resolve内部调用了MyPromise对象的resolve,并接受resolve静态方法的值;

可以连续then,明显就是又返回了一个MyPromise对象。

核心代码:

static resolve (val) {
    if(val instanceof MyPromise) return val; //如果是MyPromise对象,返回就可以。如果是普通值则创建一个Promise返回
    return new MyPromise((resolve, reject) => {
        resolve(val)
    })
}

完整代码:

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successVal = undefined;
	rejectErr = undefined;
	successCall = [];
	rejectCall = [];

    constructor(execute){
        try{
            execute(this.resolve, this.reject)
        } catch(e)  {
          return this.reject(e)   
        }
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successVal = res;
        //then 链式异步调用的时候,不需要传参
        while(this.successCall.length) this.successCall.shift()()
    }
    reject = err => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectErr = err;
        //then 链式异步调用的时候,不需要传参
        while(this.rejectCall.length) this.rejectCall.shift()()
    }
    then = (fulfilledCallBark, rejectedCallBark) => {
        //只有不是函数,都无视它,替换成val => val
        fulfilledCallBark = (fulfilledCallBark && typeof(fulfilledCallBark) === "function") ? fulfilledCallBark : val => val;
        rejectedCallBark = (rejectedCallBark && typeof(rejectedCallBark) === "function") ? rejectedCallBark : err => {throw err};

        const promise2 = new MyPromise((resolve, reject) => {
            if(this.status == fulfilled){
                //这里加定时不是为了延迟,而是让这段代码成为异步代码
                //在这里想拿到promise2是new MyPromise执行结束后才能拿到,而这里是执行的时候拿是拿不到的,需要将这段代码改成异步代码
                setTimeout(() => {  
                    //如果then的回调函数中抛出异常,则在成功状态下添加try catch进行异常处理,异常reject(e) e则是执行then中成功回调函数时出现的错误
                    try{
                    	const value = fulfilledCallBark(this.successVal);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
            			reject(e)
        		   }
                },0)
            } else if(this.status == rejected) {
                setTimeout(() => {
                    // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                    try{
                    	const value = rejectedCallBark(this.rejectErr);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
                        reject(e)
        		   }
                }, 0)
            } else {
                this.successCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = fulfilledCallBark(this.successVal);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                    
                });
                this.rejectCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = rejectedCallBark(this.rejectErr);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                });
            }		
        })
        return promise2;
    }
    //实现all 的方法
    static all (arr) {
        if(arr instanceof Array) {
            if(arr.length === 0) return arr;
            const resultArr = [];
            const arrLen = arr.length;
            const prom = new Promise((resolve, reject) => {
                while(arr.length) {
                    const current = arr.shift();
                    if(current instanceof MyPromise){
                        current.then(res => {
                            resultArr.push(res);
                            if(arrLen == resultArr.length) {
                                resolve(resultArr)
                            }
                        }, err => {
                            reject(err);
                            return err;
                        })
                    } else {
                        resultArr.push(current);
                    }
                }
            })
            return prom;
        }else {
            throw new Error(`${typeof(arr)} is not iterable (cannot read property Symbol(Symbol.iterator))`)
        }
    }
    static resolve (val) {
        if(val instanceof MyPromise) return val; //如果是MyPromise对象,返回就可以。如果是普通值则创建一个Promise返回
        return new MyPromise((resolve, reject) => {
            resolve(val)
        })
    }

    //通过resolve方法进行判断解析
    resolvePromise = (promise2, x, resolve, reject) => {
        if(promise2 === x){
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
        if(x instanceof MyPromise) {
            //Promise对象
            //x.then(res => resolve(res), err => reject(err))
            x.then(resolve, reject); 
        }else {
            resolve(x);
        }
    }
}


MyPromise.resolve(1).then().then(res => {
    console.log(res);
}, err => {
    console.log(err)
})

Promise.reject 功能实现

Promise

Promise.reject(1).then().then(res => {
    console.log(res);
}, err => {
    console.log(err)
})

MyPromise

核心:其实就是跟Promise.resolve是一样的道理

核心代码

static reject (err) {
    if(err instanceof MyPromise) return err; //如果是MyPromise对象,返回就可以。如果是普通值则创建一个Promise返回
    return new MyPromise((resolve, reject) => {
        reject(err)
    })
}

完整代码

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successVal = undefined;
	rejectErr = undefined;
	successCall = [];
	rejectCall = [];

    constructor(execute){
        try{
            execute(this.resolve, this.reject)
        } catch(e)  {
          return this.reject(e)   
        }
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successVal = res;
        //then 链式异步调用的时候,不需要传参
        while(this.successCall.length) this.successCall.shift()()
    }
    reject = err => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectErr = err;
        //then 链式异步调用的时候,不需要传参
        
        while(this.rejectCall.length) this.rejectCall.shift()()
    }
    then = (fulfilledCallBark, rejectedCallBark) => {
        //只有不是函数,都无视它,替换成val => val
        fulfilledCallBark = (fulfilledCallBark && typeof(fulfilledCallBark) === "function") ? fulfilledCallBark : val => val;
        rejectedCallBark = (rejectedCallBark && typeof(rejectedCallBark) === "function") ? rejectedCallBark : err => {throw err};

        const promise2 = new MyPromise((resolve, reject) => {
            if(this.status == fulfilled){
                //这里加定时不是为了延迟,而是让这段代码成为异步代码
                //在这里想拿到promise2是new MyPromise执行结束后才能拿到,而这里是执行的时候拿是拿不到的,需要将这段代码改成异步代码
                setTimeout(() => {  
                    //如果then的回调函数中抛出异常,则在成功状态下添加try catch进行异常处理,异常reject(e) e则是执行then中成功回调函数时出现的错误
                    try{
                    	const value = fulfilledCallBark(this.successVal);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
            			reject(e)
        		   }
                },0)
            } else if(this.status == rejected) {
                setTimeout(() => {
                    // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                    try{
                    	const value = rejectedCallBark(this.rejectErr);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
                        reject(e)
        		   }
                }, 0)
            } else {
                this.successCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = fulfilledCallBark(this.successVal);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                    
                });
                this.rejectCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = rejectedCallBark(this.rejectErr);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                });
            }		
        })
        return promise2;
    }
    //实现all 的方法
    static all (arr) {
        if(arr instanceof Array) {
            if(arr.length === 0) return arr;
            const resultArr = [];
            const arrLen = arr.length;
            const prom = new Promise((resolve, reject) => {
                while(arr.length) {
                    const current = arr.shift();
                    if(current instanceof MyPromise){
                        current.then(res => {
                            resultArr.push(res);
                            if(arrLen == resultArr.length) {
                                resolve(resultArr)
                            }
                        }, err => {
                            reject(err);
                            return err;
                        })
                    } else {
                        resultArr.push(current);
                    }
                }
            })
            return prom;
        }else {
            throw new Error(`${typeof(arr)} is not iterable (cannot read property Symbol(Symbol.iterator))`)
        }
    }
    static resolve (val) {
        if(val instanceof MyPromise) return val; //如果是MyPromise对象,返回就可以。如果是普通值则创建一个Promise返回
        return new MyPromise((resolve, reject) => {
            resolve(val)
        })
    }
    static reject (err) {
        if(err instanceof MyPromise) return err; //如果是MyPromise对象,返回就可以。如果是普通值则创建一个Promise返回
        return new MyPromise((resolve, reject) => {
            reject(err)
        })
    }

    //通过resolve方法进行判断解析
    resolvePromise = (promise2, x, resolve, reject) => {
        if(promise2 === x){
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
        if(x instanceof MyPromise) {
            //Promise对象
            //x.then(res => resolve(res), err => reject(err))
            x.then(resolve, reject); 
        }else {
            resolve(x);
        }
    }
}


MyPromise.resolve(1).then().then(res => {
    console.log(res);
}, err => {
    console.log(err)
})
MyPromise.resolve().then().then(res => {
    console.log(res);
}, err => {
    console.log(err)
})
MyPromise.reject("失败了").then(res => {
    console.log(res)
}, err => {
    console.log("失败then1 err", err)
})

Promise 中finally 方法的实现

Promise

const prom = new Promise((resolve, reject) => {
    resolve('成功')
})
prom.finally(() => {
    console.log("finally");
}).then(res => {
	console.log(res);
}, err => {
	console.log(err)
}).finally(() => {
    console.log("finally2");
})

MyPromise

核心:

1、可以看出finally它不是静态是方法,是原型方法。

2、finally 返回then的结果

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successVal = undefined;
	rejectErr = undefined;
	successCall = [];
	rejectCall = [];

    constructor(execute){
        try{
            execute(this.resolve, this.reject)
        } catch(e)  {
          return this.reject(e)   
        }
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successVal = res;
        //then 链式异步调用的时候,不需要传参
        while(this.successCall.length) this.successCall.shift()()
    }
    reject = err => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectErr = err;
        //then 链式异步调用的时候,不需要传参
        
        while(this.rejectCall.length) this.rejectCall.shift()()
    }
    then = (fulfilledCallBark, rejectedCallBark) => {
        //只有不是函数,都无视它,替换成val => val
        fulfilledCallBark = (fulfilledCallBark && typeof(fulfilledCallBark) === "function") ? fulfilledCallBark : val => val;
        rejectedCallBark = (rejectedCallBark && typeof(rejectedCallBark) === "function") ? rejectedCallBark : err => {throw err};

        const promise2 = new MyPromise((resolve, reject) => {
            if(this.status == fulfilled){
                //这里加定时不是为了延迟,而是让这段代码成为异步代码
                //在这里想拿到promise2是new MyPromise执行结束后才能拿到,而这里是执行的时候拿是拿不到的,需要将这段代码改成异步代码
                setTimeout(() => {  
                    //如果then的回调函数中抛出异常,则在成功状态下添加try catch进行异常处理,异常reject(e) e则是执行then中成功回调函数时出现的错误
                    try{
                    	const value = fulfilledCallBark(this.successVal);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
            			reject(e)
        		   }
                },0)
            } else if(this.status == rejected) {
                setTimeout(() => {
                    // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                    try{
                    	const value = rejectedCallBark(this.rejectErr);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
                        reject(e)
        		   }
                }, 0)
            } else {
                this.successCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = fulfilledCallBark(this.successVal);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                    
                });
                this.rejectCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = rejectedCallBark(this.rejectErr);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                });
            }		
        })
        return promise2;
    }
    //实现all 的方法
    static all (arr) {
        if(arr instanceof Array) {
            if(arr.length === 0) return arr;
            const resultArr = [];
            const arrLen = arr.length;
            const prom = new Promise((resolve, reject) => {
                while(arr.length) {
                    const current = arr.shift();
                    if(current instanceof MyPromise){
                        current.then(res => {
                            resultArr.push(res);
                            if(arrLen == resultArr.length) {
                                resolve(resultArr)
                            }
                        }, err => {
                            reject(err);
                            return err;
                        })
                    } else {
                        resultArr.push(current);
                    }
                }
            })
            return prom;
        }else {
            throw new Error(`${typeof(arr)} is not iterable (cannot read property Symbol(Symbol.iterator))`)
        }
    }
    finally = (callBark) => {
        return this.then(res => {
            if(typeof(callBark) === 'function') {
                return MyPromise.resolve(callBark()).then(res => res)
            }
        }, err => {
            return MyPromise.reject(callBark()).then(() => {throw err})
        })
    }
    static resolve (val) {
        if(val instanceof MyPromise) return val; //如果是MyPromise对象,返回就可以。如果是普通值则创建一个Promise返回
        return new MyPromise((resolve, reject) => {
            resolve(val)
        })
    }
    static reject (err) {
        if(err instanceof MyPromise) return err; //如果是MyPromise对象,返回就可以。如果是普通值则创建一个Promise返回
        return new MyPromise((resolve, reject) => {
            reject(err)
        })
    }

    //通过resolve方法进行判断解析
    resolvePromise = (promise2, x, resolve, reject) => {
        if(promise2 === x){
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
        if(x instanceof MyPromise) {
            //Promise对象
            //x.then(res => resolve(res), err => reject(err))
            x.then(resolve, reject); 
        }else {
            resolve(x);
        }
    }
}

function fun1() {
    return new MyPromise((resolve, reject) => {
        resolve('成功1')
        // reject("失败")
        // setTimeout(() => {
        // resolve('成功')
        // reject("失败")
        // }, 6000)
    })
}
function fun2 () {
    return new MyPromise((resolve, reject) => {
        setTimeout(() => {
            resolve('成功222')
            // reject("失败")
        }, 5000)
    })
}

// fun1().finally(() => {
//     console.log("finally");
// }).then(res => {
// 	console.log('then1',res);
//     return fun2();
// }, err => {
// 	console.log(err)
// }).finally(() => {
//     console.log("finally2");
// }).then(res => {
// 	console.log("then2 成",res);
//     return res;
// }, err => {
// 	console.log("then2 败",err)
// }).finally(() => {
//     console.log("finally3");
// }).then(res => {
// 	console.log("then3 成",res);

// }, err => {
// 	console.log("then3 败",err)
// })

fun1().finally(() => {
    console.log("finally");
    return fun2();
}).then(res => {
	console.log('then1',res);
}, err => {
	console.log(err)
})

Promise.catch方法的实现

Promise

const prom = new Promise((resolve, reject) => {
    reject("失败了")
})
prom.then(res => {
    console.log(res)
}).catch(err => {
    console.log(err)
})

MyPromise

核心代码

catch (callBark) {
    return this.then(undefined,callBark);
}

完整代码

const pending = 'PENDING';
const fulfilled = 'FULFILLED';
const rejected = 'REJECTED';

class MyPromise{
    status = pending;
	successVal = undefined;
	rejectErr = undefined;
	successCall = [];
	rejectCall = [];

    constructor(execute){
        try{
            execute(this.resolve, this.reject)
        } catch(e)  {
          return this.reject(e)   
        }
    }
    resolve = res => {
        if(this.status !== pending) return;
        this.status = fulfilled;
        this.successVal = res;
        //then 链式异步调用的时候,不需要传参
        while(this.successCall.length) this.successCall.shift()()
    }
    reject = err => {
        if(this.status !== pending) return;
        this.status = rejected;
        this.rejectErr = err;
        //then 链式异步调用的时候,不需要传参
        
        while(this.rejectCall.length) this.rejectCall.shift()()
    }
    then = (fulfilledCallBark, rejectedCallBark) => {
        //只有不是函数,都无视它,替换成val => val
        fulfilledCallBark = (fulfilledCallBark && typeof(fulfilledCallBark) === "function") ? fulfilledCallBark : val => val;
        rejectedCallBark = (rejectedCallBark && typeof(rejectedCallBark) === "function") ? rejectedCallBark : err => {throw err};

        const promise2 = new MyPromise((resolve, reject) => {
            if(this.status == fulfilled){
                //这里加定时不是为了延迟,而是让这段代码成为异步代码
                //在这里想拿到promise2是new MyPromise执行结束后才能拿到,而这里是执行的时候拿是拿不到的,需要将这段代码改成异步代码
                setTimeout(() => {  
                    //如果then的回调函数中抛出异常,则在成功状态下添加try catch进行异常处理,异常reject(e) e则是执行then中成功回调函数时出现的错误
                    try{
                    	const value = fulfilledCallBark(this.successVal);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
            			reject(e)
        		   }
                },0)
            } else if(this.status == rejected) {
                setTimeout(() => {
                    // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                    try{
                    	const value = rejectedCallBark(this.rejectErr);
                    	this.resolvePromise(promise2, value, resolve, reject);
                    } catch(e) {
                        reject(e)
        		   }
                }, 0)
            } else {
                this.successCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = fulfilledCallBark(this.successVal);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                    
                });
                this.rejectCall.push(() => {
                    setTimeout(() => {
                        // 如果then的回调函数中 失败回调函数出现异常,则在失败状态下添加try catch进行异常处理,异常reject(e), e 则是执行then中失败回调函数时出现的错误
                        try{
                            const value = rejectedCallBark(this.rejectErr);
                            this.resolvePromise(promise2, value, resolve, reject);
                        } catch(e) {
                            reject(e)
                       }
                    }, 0)
                });
            }		
        })
        return promise2;
    }
    //实现all 的方法
    static all (arr) {
        if(arr instanceof Array) {
            if(arr.length === 0) return arr;
            const resultArr = [];
            const arrLen = arr.length;
            const prom = new Promise((resolve, reject) => {
                while(arr.length) {
                    const current = arr.shift();
                    if(current instanceof MyPromise){
                        current.then(res => {
                            resultArr.push(res);
                            if(arrLen == resultArr.length) {
                                resolve(resultArr)
                            }
                        }, err => {
                            reject(err);
                            return err;
                        })
                    } else {
                        resultArr.push(current);
                    }
                }
            })
            return prom;
        }else {
            throw new Error(`${typeof(arr)} is not iterable (cannot read property Symbol(Symbol.iterator))`)
        }
    }
    finally = (callBark) => {
        return this.then(res => {
            if(typeof(callBark) === 'function') {
                return MyPromise.resolve(callBark()).then(res => res)
            }
        }, err => {
            return MyPromise.reject(callBark()).then(() => {throw err})
        })
    }
    catch (rejectedCallBark) {
        return this.then(undefined, rejectedCallBark);
    }
    static resolve (val) {
        if(val instanceof MyPromise) return val; //如果是MyPromise对象,返回就可以。如果是普通值则创建一个Promise返回
        return new MyPromise((resolve, reject) => {
            resolve(val)
        })
    }
    static reject (err) {
        if(err instanceof MyPromise) return err; //如果是MyPromise对象,返回就可以。如果是普通值则创建一个Promise返回
        return new MyPromise((resolve, reject) => {
            reject(err)
        })
    }

    //通过resolve方法进行判断解析
    resolvePromise = (promise2, x, resolve, reject) => {
        if(promise2 === x){
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
        if(x instanceof MyPromise) {
            //Promise对象
            //x.then(res => resolve(res), err => reject(err))
            x.then(resolve, reject); 
        }else {
            resolve(x);
        }
    }
}

function fun1() {
    return new MyPromise((resolve, reject) => {
        // resolve('成功1')
        reject("失败")
    })
}

fun1().then(res => console.log('then1',res)).catch(err => {
    console.log(err)
})