学习笔记 手写 Promise 2021-06-06

这篇学习笔记详细介绍了如何手写Promise,涵盖了基本功能、内部异步逻辑、then方法的多次调用和链式调用、错误捕获、参数可选等多个方面,深入理解Promise的工作原理。
摘要由CSDN通过智能技术生成

学习笔记 手写 Promise


前言

Promise基本功能、Promise.then()、Promise.reject()、Promise.resolve()、Promise.catch()、Promise.finally()、Promise.all()、Promise.race()、Promise.then()链式调用、Promise.then()参数可选的实现

一、Promise 基本功能的实现

Promise示例:

	let promise = new Promise((resolve, reject) => {
        resolve('成功')
        // reject('失败')
    });
    promise.then(value => console.log(value), reason => console.log(reason))
    
    // 结果:
    //	resolve('成功') ----> 成功
    // 	reject('失败') ----> 失败
    

1. 实现思路

  • Promise是一个类,可以使用 new 来调用 Promise 的构造器来进行实例化;

  • 在执行这个类的时候,需要传递一个带有 resolve(解析)和 reject(拒绝)两个参数的执行器进去,执行器会立即执行;

  • 在 Promise 中有三种状态,分别为pending(等待 )、fulfilled(成功 )、 rejected(失败);

  • resolve 和 reject 函数是用来更改状态的(状态一旦确定,就不能更改)
    resolve:pending(等待) ====> fulfilled(成功)
    reject:pending(等待) ====> rejected(失败)

  • then 方法内部做的事情就是判断状态,then 方法是被定义在原型变量中的。
    如果状态是成功,调用成功回调函数;
    如果状态是失败,调用失败回调函数。

  • then成功回调有一个参数,表示成功之后的值;
    then失败回调有一个参数,表示失败之后的原因。

2. MyPromise实现

	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败

	class MyPromise {
	    constructor(executor) {
	        // 执行器传进来,立即执行
	        executor(this.resolve, this.reject)
	    }
	    // 状态,初始值为 pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 undefined
	    value = undefined
	    // 保存失败的值,默认 undefined
	    reason = undefined
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	    }

	    then = (successCallBack, failCallBack) => {
	        // successCallBack, failCallBack 是function
	        if (this.status === FULFILLED) {
	            // 状态为成功,调用成功回调函数
	            successCallBack(this.value)
	        } else if (this.status === REJECTED) {
	            // 状态为失败,调用失败回调函数
	            failCallBack(this.reason)
	        }
	    }
	}

	let promise = new MyPromise((resolve, reject) => {
	    // resolve('成功')
	    reject('失败')
	});
	promise.then(value => console.log(value), reason => console.log(reason))
    // 结果:
    //	resolve('成功') ----> 成功
    // 	reject('失败') ----> 失败

二、Promise 内部异步逻辑的实现

Promise内部异步示例:

	let promise = new Promise((resolve, reject) => {
        setTimeout(() => resolve('成功'), 2000)
        // setTimeout(() => reject('失败'), 2000)
    });
    promise.then(value => console.log(value), reason => console.log(reason))
    
    // 结果:
    //	setTimeout(() => resolve('成功'), 2000) ----> 2秒后打印 成功
    // 	setTimeout(() => reject('失败'), 2000) ----> 2秒后打印 失败
    

1. 问题产生

MyPromise内部使用异步:

	let promise = new MyPromise((resolve, reject) => {
        setTimeout(() => resolve('成功'), 2000)
        // setTimeout(() => reject('失败'), 2000)
    });
    promise.then(value => console.log(value), reason => console.log(reason))
    
    // 结果:
    //	setTimeout(() => resolve('成功'), 2000) ----> 没东西打印出来
    // 	setTimeout(() => reject('失败'), 2000) ----> 没东西打印出来
    
  • 这时候发现自己的实现的MyPromise输出结果没有跟Promise的一样

问题分析: new MyPromise( ‘执行器’ ) 中的 ‘执行器’ 会立即执行,当 ‘执行器’执行的时候,会发现里面的代码是异步代码,异步代码会被挂载到 ‘消息队列’ 中,主线程不会等待两秒,会继续执行直到没有任务,再去执行 ‘消息队列’ 的任务,所以promise.then( ‘内容’ )里面的 ‘内容’ 会马上被执行。上述MyPromise里的 then 只判断了两种状态(‘fulfilled(成功)’ 和 ‘rejected(失败)’,没有判断 'pending(等待)'状态,并且promise两秒钟后才改变状态,这时的状态是 ‘pending(等待)’;两秒钟后才resolve,这时then早就已经执行完毕了,所以不会打印结果出来。

解决方案: MyPromise里的 then 增加状态 ‘pending(等待)’ 状态的判断。

2. MyPromise 内部异步实现

MyPromise 增加内部异步:

	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
	    constructor(executor) {
	        // 执行器传进来,立即执行
	        executor(this.resolve, this.reject)
	    }
	    // 状态,初始为pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 没有
	    value = undefined
	    // 保存失败的值,默认 没有
	    reason = undefined
	    // 保存成功回调
	    successCallBack = undefined
	    // 保存失败回调
	    failCallBack = undefined
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	        // 判断成功回调是否存在
	        this.successCallBack && this.successCallBack(this.value)
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	        // 判断失败回调是否存在
	        this.failCallBack && this.failCallBack(this.reason)
	    }
	
	    then = (successCallBack, failCallBack) => {
	        // successCallBack, failCallBack 是function
	        if (this.status === FULFILLED) {
	            // 状态为成功,调用成功回调函数
	            successCallBack(this.value)
	        } else if (this.status === REJECTED) {
	            // 状态为失败,调用失败回调函数
	            failCallBack(this.reason)
	        } else {
	            // 状态为等待
	            // 将成功回调、失败回调 存储起来
	            this.successCallBack = successCallBack
	            this.failCallBack = failCallBack
	        }
	    }
	}
	
	let promise = new MyPromise((resolve, reject) => {
  	    // resolve('成功')
	    // reject('失败')
	    setTimeout(() => resolve('成功'), 2000)
	    // setTimeout(() => resolve('成功'), 2000)
	});
	promise.then(value => console.log(value), reason => console.log(reason))
	
    // 结果:
    //	resolve('成功') ----> 成功
    // 	reject('失败') ----> 失败
    //  setTimeout(() => resolve('成功'), 2000) ----> 2秒后打印 成功
	//  setTimeout(() => reject('失败'), 2000) ----> 2秒后打印 失败
	    

三、Promise.then 方法多次调用添加多个处理函数的实现

Promise then 方法多次调用示例:

	let promise = new Promise((resolve, reject) => {
        // setTimeout(() => resolve('成功'), 2000)
        resolve('成功')
        // reject('失败')
    });
    promise.then(value => console.log(value), reason => console.log(reason))
    promise.then(value => console.log(value), reason => console.log(reason))
    promise.then(value => console.log(value), reason => console.log(reason))
    
    // 结果:
    //	setTimeout(() => resolve('成功'), 2000) ----> 两秒钟后打印 成功 成功 成功
    // 	resolve('成功') ----> 成功 成功 成功
    // 	reject('失败') ----> 失败 失败 失败
    

1. 问题产生

MyPromise then 方法多次调用示例:

	let promise = new MyPromise((resolve, reject) => {
        setTimeout(() => resolve('成功'), 2000)
        // setTimeout(() => reject('失败'), 2000)
    });
    promise.then(value => console.log(value), reason => console.log(reason))
    
    // 结果:
    //	setTimeout(() => resolve('成功'), 2000) ----> 两秒钟后打印 成功
    // 	resolve('成功') ----> 成功 成功 成功
    // 	reject('失败') ----> 失败 失败 失败
    
  • 这时候发现自己的实现的MyPromise输出结果没有跟Promise的一样,在异步调用时候没有 输出 三次 ‘成功’

问题分析: 在 MyPromise( ‘执行器’ ) then中异步调用中,因为之前 successCallBack = undefined、failCallBack = undefined 只能存储一个函数,多个异步调用会覆盖掉之前的,只保留最后的一个。

解决方案: 将 MyPromise里的successCallBack 和 failCallBack 变成数组,successCallBack = [ ]、failCallBack = [ ]。

2. MyPromise.then 方法多次调用实现

MyPromise 增加 then 方法多次调用:

	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
	    constructor(executor) {
	        // 执行器传进来,立即执行
	        executor(this.resolve, this.reject)
	    }
	    // 状态,初始为pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 没有
	    value = undefined
	    // 保存失败的值,默认 没有
	    reason = undefined
	    // 保存成功回调
	    successCallBack = []
	    // 保存失败回调
	    failCallBack = []
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	        // 判断成功回调是否存在
	        // this.successCallBack && this.successCallBack(this.value)
	        while (this.successCallBack.length) this.successCallBack.shift()(this.value)
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	        // 判断失败回调是否存在
	        // this.failCallBack && this.failCallBack(this.reason)
	        while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
	    }
	
	    then = (successCallBack, failCallBack) => {
	        // successCallBack, failCallBack 是function
	        if (this.status === FULFILLED) {
	            // 状态为成功,调用成功回调函数
	            successCallBack(this.value)
	        } else if (this.status === REJECTED) {
	            // 状态为失败,调用失败回调函数
	            failCallBack(this.reason)
	        } else {
	            // 状态为等待
	            // 将成功回调、失败回调 存储起来
	            this.successCallBack.push(successCallBack)
	            this.failCallBack.push(failCallBack)
	        }
	    }
	}
	
	let promise = new MyPromise((resolve, reject) => {
	    setTimeout(() => resolve('成功'), 2000)
	    // resolve('成功')
	    // reject('失败')
	});
	promise.then(value => console.log(value), reason => console.log(reason))
	promise.then(value => console.log(value), reason => console.log(reason))
	promise.then(value => console.log(value), reason => console.log(reason))
	    
    // 结果:
    //	setTimeout(() => resolve('成功'), 2000) ----> 两秒钟后打印 成功
    // 	resolve('成功') ----> 成功 成功 成功
    // 	reject('失败') ----> 失败 失败 失败
    

四、Promise.then 方法的链式调用的实现(一)

Promise then 方法链式调用示例:

	let promise = new Promise((resolve, reject) => {
        // setTimeout(() => resolve('成功'), 2000)
        resolve('成功')
        // reject('失败')
    });
    promise
        .then(value => {
            console.log(value)
            return 123
        })
        .then(value => console.log(value))
    
    // 结果:
    //	成功
    //  100
    
  • then方法是可以被链式调用的, 后面then方法的回调函数拿到值的是上一个then方法的回调函数的返回值

1. 实现思路

  • then方法是promise对象实现调用的,如果想实现then链式调用,那么promise返回的值也应该是promise对象

2. 实现Promise.then 方法链式链式调用

	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
	    constructor(executor) {
	        // 执行器传进来,立即执行
	        executor(this.resolve, this.reject)
	    }
	    // 状态,初始为pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 没有
	    value = undefined
	    // 保存失败的值,默认 没有
	    reason = undefined
	    // 保存成功回调
	    successCallBack = []
	    // 保存失败回调
	    failCallBack = []
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	        // 判断成功回调是否存在
	        // this.successCallBack && this.successCallBack(this.value)
	        while (this.successCallBack.length) this.successCallBack.shift()(this.value)
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	        // 判断失败回调是否存在
	        // this.failCallBack && this.failCallBack(this.reason)
	        while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
	    }
	
	    then = (successCallBack, failCallBack) => {
	        // 实现then 方法返回一个promise对象
	        let promise2 = new MyPromise((resolve, reject) => {
	            // successCallBack, failCallBack 是function
	            if (this.status === FULFILLED) {
	                // 状态为成功,调用成功回调函数
	                let x = successCallBack(this.value)
	                resolve(x)
	            } else if (this.status === REJECTED) {
	                // 状态为失败,调用失败回调函数
	                failCallBack(this.reason)
	            } else {
	                // 状态为等待
	                // 将成功回调、失败回调 存储起来
	                this.successCallBack.push(successCallBack)
	                this.failCallBack.push(failCallBack)
	            }
	        })
	        return promise2
	    }
	}
	
	let promise = new MyPromise((resolve, reject) => {
	    resolve('成功')
	});
	promise
	    .then(value => {
	        console.log(value)
	        return 123
	    })
	    .then(value => console.log(value))
    
    // 结果:
    //	成功
    //  100
    

五、Promise.then 方法的链式调用的实现(二)

  • 在Promise then 方法的链式调用的时候,可以返回一个普通值,也可以返回一个 promise 对象。
  • 如果返回的是一个值可以直接调用 resolve(),传递给下一个promise 对象。
  • 如果返回的是一个 promise 对象,要先查看这个promise 对象的状态(status)。若返回的 promise 对象的状态是 fulfilled 则调用resolve方法,把成功的结果传递给下一个对象;若返回的 promise 对象的状态是 rejected 则调用 reject 方法,把失败的原因传递给下一个对象。

MyPromise then 方法链式调用示例:

	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
	    constructor(executor) {
	        // 执行器传进来,立即执行
	        executor(this.resolve, this.reject)
	    }
	    // 状态,初始为pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 没有
	    value = undefined
	    // 保存失败的值,默认 没有
	    reason = undefined
	    // 保存成功回调
	    successCallBack = []
	    // 保存失败回调
	    failCallBack = []
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	        // 判断成功回调是否存在
	        // this.successCallBack && this.successCallBack(this.value)
	        while (this.successCallBack.length) this.successCallBack.shift()(this.value)
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	        // 判断失败回调是否存在
	        // this.failCallBack && this.failCallBack(this.reason)
	        while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
	    }
	
	    then = (successCallBack, failCallBack) => {
	        // 实现then 方法返回一个promise对象
	        let promise2 = new MyPromise((resolve, reject) => {
	            // successCallBack, failCallBack 是function
	            if (this.status === FULFILLED) {
	                // 状态为成功,调用成功回调函数
	                let x = successCallBack(this.value)
	                // resolve(x)
	                // 判断 X 的值是普通还是promise对象
	                // 如果是普通值 直接调用resolve
	                // 如果是promise对象 查看promise对象返回结果
	                // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                resolvePromise(x, resolve, reject)
	            } else if (this.status === REJECTED) {
	                // 状态为失败,调用失败回调函数
	                failCallBack(this.reason)
	            } else {
	                // 状态为等待
	                // 将成功回调、失败回调 存储起来
	                this.successCallBack.push(successCallBack)
	                this.failCallBack.push(failCallBack)
	            }
	        })
	        return promise2
	    }
	}
	
	function resolvePromise (x, resolve, reject) {
	    if (x instanceof MyPromise) {
	        // promise 对象
	        // x.then(value => resolve(value), reason => reject(reason))
	        x.then(resolve, reject)
	    } else {
	        // 普通值
	        resolve(x)
	    }
	}
	
	// 测试
	let promise = new MyPromise((resolve, reject) => {
	    resolve('成功')
	});
	
	function other () {
	    return new MyPromise((resolve, reject) => {
	        resolve('other')
	    })
	}
	
	promise
	    .then(value => {
	        console.log(value)
	        return other()
	    })
	    .then(value => console.log(value))
    
    // 结果:
    //	成功
    //  other
    

六、Promise.then 方法的链式调用识别自身的实现

Promise then 方法调用自身 示例:

	
    let promise = new Promise((resolve, reject) => {
        resolve('成功')
    });

    let p1 = promise
        .then(value => {
            console.log(value)
            return p1
        })
    // p1.then(() => { }, reason => console.log(reason.message))
    
    // 结果:
    //	成功
    // 	Uncaught (in promise) TypeError: Chaining cycle detected for promise #<Promise>  // 报错
    // p1.then(() => { }, reason => console.log(reason.message)) // 会输出错误的信息
    

MyPromise then 方法调用识别自身 示例:

	
    const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
	    constructor(executor) {
	        // 执行器传进来,立即执行
	        executor(this.resolve, this.reject)
	    }
	    // 状态,初始为pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 没有
	    value = undefined
	    // 保存失败的值,默认 没有
	    reason = undefined
	    // 保存成功回调
	    successCallBack = []
	    // 保存失败回调
	    failCallBack = []
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	        // 判断成功回调是否存在
	        // this.successCallBack && this.successCallBack(this.value)
	        while (this.successCallBack.length) this.successCallBack.shift()(this.value)
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	        // 判断失败回调是否存在
	        // this.failCallBack && this.failCallBack(this.reason)
	        while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
	    }
	
	    then = (successCallBack, failCallBack) => {
	        // 实现then 方法返回一个promise对象
	        let promise2 = new MyPromise((resolve, reject) => {
	            // successCallBack, failCallBack 是function
	            if (this.status === FULFILLED) {
	                // 把这部分的代码变成异步,才能正常获取promise2
	                setTimeout(() => {
	                    // 状态为成功,调用成功回调函数
	                    let x = successCallBack(this.value)
	                    // resolve(x)
	                    // 判断 X 的值是普通还是promise对象
	                    // 如果是普通值 直接调用resolve
	                    // 如果是promise对象 查看promise对象返回结果
	                    // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                    resolvePromise(promise2, x, resolve, reject)
	                }, 0)
	            } else if (this.status === REJECTED) {
	                // 状态为失败,调用失败回调函数
	                failCallBack(this.reason)
	            } else {
	                // 状态为等待
	                // 将成功回调、失败回调 存储起来
	                this.successCallBack.push(successCallBack)
	                this.failCallBack.push(failCallBack)
	            }
	        })
	        return promise2
	    }
	}
	
	function 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(value => resolve(value), reason => reject(reason))
	        x.then(resolve, reject)
	    } else {
	        // 普通值
	        resolve(x)
	    }
	}
	
	// 测试
	let promise = new MyPromise((resolve, reject) => {
	    resolve('成功')
	});
	
	let p1 = promise.then(value => {
	    console.log(value)
	    return p1
	})
	
	p1.then(value => console.log(value), reason => console.log(reason.message))
    
    // 结果:
    //	成功
    //  Chaining cycle detected for promise #<Promise>  // 报错信息
    

七、Promise 捕获错误的实现

Promise then 方法捕获错误 示例:

	// 情况一
    let promise = new MyPromise((resolve, reject) => {
	    throw TypeError('抛出一个错误')
	    resolve('成功')
	});
	promise.then(value => console.log(value), reason => console.log(reason.message))
	
    // 结果:
    // 	抛出一个错误  // 报错

	// 情况二
	let promise2 = new Promise((resolve, reject) => {
	        resolve('成功')
	    });
	promise2
        .then(value => {
            console.log(value)
            throw TypeError('抛出一个错误')
            console.log('123')
        }, reason => {
            console.log(reason)
        }).then(value => console.log(value), reason => console.log(reason.message))
        
    // 结果:
    //  成功
    // 	抛出一个错误  // 报错
    

1. 实现思路

  1. 情况一:在 MyPromise 类的构造函数中增加 try catch 异常捕获
  2. 情况二:在 MyPromise 的 then 方法中 成功回调、失败回调、异步回调 增加 try catch 异常捕获

2. 实现捕获错误

	
	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
	    constructor(executor) {
	        try {
	            // 执行器传进来,立即执行
	            executor(this.resolve, this.reject)
	        } catch (e) {
	            this.reject(e)
	        }
	    }
	    // 状态,初始为pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 没有
	    value = undefined
	    // 保存失败的值,默认 没有
	    reason = undefined
	    // 保存成功回调
	    successCallBack = []
	    // 保存失败回调
	    failCallBack = []
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	        // 判断成功回调是否存在
	        // this.successCallBack && this.successCallBack(this.value)
	        // while (this.successCallBack.length) this.successCallBack.shift()(this.value)
	        while (this.successCallBack.length) this.successCallBack.shift()()
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	        // 判断失败回调是否存在
	        // this.failCallBack && this.failCallBack(this.reason)
	        // while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
	        while (this.failCallBack.length) this.failCallBack.shift()()
	    }
	
	    then = (successCallBack, failCallBack) => {
	        // 实现then 方法返回一个promise对象
	        let promise2 = new MyPromise((resolve, reject) => {
	            // successCallBack, failCallBack 是function
	            if (this.status === FULFILLED) {
	                // 把这部分的代码变成异步,才能正常获取promise2
	                setTimeout(() => {
	                    try {
	                        // 状态为成功,调用成功回调函数
	                        let x = successCallBack(this.value)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else if (this.status === REJECTED) {
	                setTimeout(() => {
	                    try {
	                        // 状态为失败,调用失败回调函数
	                        failCallBack(this.reason)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else {
	                // 状态为等待
	                // 将成功回调、失败回调 存储起来
	                this.successCallBack.push(() => {
	                    // successCallBack()
	                    setTimeout(() => {
	                        try {
	                            // 状态为成功,调用成功回调函数
	                            let x = successCallBack(this.value)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	                this.failCallBack.push(() => {
	                    setTimeout(() => {
	                        // failCallBack()
	                        try {
	                            // 状态为失败,调用失败回调函数
	                            failCallBack(this.reason)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	            }
	        })
	        return promise2
	    }
	}
	
	function 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(value => resolve(value), reason => reject(reason))
	        x.then(resolve, reject)
	    } else {
	        // 普通值
	        resolve(x)
	    }
	}
	
	// 打印出的结果会有异步情况的出现
	
	// 测试一
	let promise1 = new MyPromise((resolve, reject) => {
	    throw new Error('抛出一个错误')
	    resolve('成功')
	});
	promise1
	    .then(value => console.log('测试一', value), reason => console.log('测试一', reason.message))
	// 测试一 结果:
	//  抛出一个错误
	
	// 测试二 成功
	let promise2 = new MyPromise((resolve, reject) => {
	    // throw new Error('抛出一个错误')
	    resolve('成功')
	});
	promise2
	    .then(value => {
	        console.log('测试二', value)
	        throw new Error('抛出一个错误')
	    }, reason => console.log('测试二', reason.message))
	    .then(value => console.log('测试二', value), reason => console.log('测试二', reason.message))
   	// 测试二 结果:
	//  测试二 成功
	//  测试二 抛出一个错误
	
	// 测试三 失败
	let promise3 = new MyPromise((resolve, reject) => {
	    reject('失败')
	});
	promise3
	    .then(value => {
	        console.log('测试三', value)
	    }, reason => {
	        console.log('测试三', reason)
	        throw new Error('抛出一个错误')
	    })
	    .then(value => console.log('测试三', value), reason => console.log('测试三', reason.message))
    
    // 测试三 结果:
	//  测试三 失败
	//  测试三 抛出一个错误
	
	// 测试四 异步
	let promise4 = new MyPromise((resolve, reject) => {
	    setTimeout(() => resolve('成功'), 2000)
	});
	promise4
	    .then(value => {
	        console.log('测试四', value)
	        throw new Error('抛出一个错误')
	        // return 'aaaa'
	    }, reason => {
	        console.log('测试四', reason)
	    })
	    .then(value => console.log('测试四', value), reason => console.log('测试四', reason.message))

  	// 测试四 结果: 两秒钟后打印
	//  测试四 成功
	//  测试四 抛出一个错误
    

八、Promise.then 方法的参数变成可选参数的实现

Promise then 方法的参数可选 示例:

	let promise = new Promise((resolve, reject) => {
        resolve('成功')
    });

    promise.then().then().then(value => console.log(value))
    
    // 结果:
    //	成功
    

1. 实现思路

	let promise = new Promise((resolve, reject) => {
        resolve('成功')
    });

    promise
	    .then(value => value)
	    .then(value => value)
	    .then(value => console.log(value))
    
    // 结果:
    //	成功
    
  1. 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给 successCallBack
  2. 判断 failCallBack 是否存在,存在则直接调用 failCallBack,否则 reason => { throw reason } 重新赋值给 failCallBack

2. 实现 Promise.then 方法的参数变成可选参数示例

	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
	    constructor(executor) {
	        try {
	            // 执行器传进来,立即执行
	            executor(this.resolve, this.reject)
	        } catch (e) {
	            this.reject(e)
	        }
	    }
	    // 状态,初始为pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 没有
	    value = undefined
	    // 保存失败的值,默认 没有
	    reason = undefined
	    // 保存成功回调
	    successCallBack = []
	    // 保存失败回调
	    failCallBack = []
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	        // 判断成功回调是否存在
	        // this.successCallBack && this.successCallBack(this.value)
	        // while (this.successCallBack.length) this.successCallBack.shift()(this.value)
	        while (this.successCallBack.length) this.successCallBack.shift()()
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	        // 判断失败回调是否存在
	        // this.failCallBack && this.failCallBack(this.reason)
	        // while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
	        while (this.failCallBack.length) this.failCallBack.shift()()
	    }
	
	    then = (successCallBack, failCallBack) => {
	        // 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
	        successCallBack = successCallBack ? successCallBack : value => value
	        failCallBack = failCallBack ? failCallBack : reason => { throw reason }
	        // 实现then 方法返回一个promise对象
	        let promise2 = new MyPromise((resolve, reject) => {
	            // successCallBack, failCallBack 是function
	            if (this.status === FULFILLED) {
	                // 把这部分的代码变成异步,才能正常获取promise2
	                setTimeout(() => {
	                    try {
	                        // 状态为成功,调用成功回调函数
	                        let x = successCallBack(this.value)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else if (this.status === REJECTED) {
	                setTimeout(() => {
	                    try {
	                        // 状态为失败,调用失败回调函数
	                        failCallBack(this.reason)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else {
	                // 状态为等待
	                // 将成功回调、失败回调 存储起来
	                this.successCallBack.push(() => {
	                    // successCallBack()
	                    setTimeout(() => {
	                        try {
	                            // 状态为成功,调用成功回调函数
	                            let x = successCallBack(this.value)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	                this.failCallBack.push(() => {
	                    setTimeout(() => {
	                        // failCallBack()
	                        try {
	                            // 状态为失败,调用失败回调函数
	                            failCallBack(this.reason)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	            }
	        })
	        return promise2
	    }
	}
	
	function 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(value => resolve(value), reason => reject(reason))
	        x.then(resolve, reject)
	    } else {
	        // 普通值
	        resolve(x)
	    }
	}

	// 测试
	let promise1 = new MyPromise((resolve, reject) => {
	    // throw new Error('抛出一个错误')
	    resolve('成功')
	    // reject('失败')
	});
	promise1
	    .then()
	    .then()
	    .then(value => console.log(value), reason => console.log(reason))
	    
    // 结果:
    //	resolve('成功') ----> 成功
    //	reject('失败') ----> 失败
    //	throw new Error('抛出一个错误') ----> Error: 抛出一个错误
    

九、Promise.all 方法的实现

Promise.all 方法示例:

	function p1() {
        return new Promise((resolve, reject) => {
            setTimeout(() => resolve('p1'), 2000)
        })
    }

    function p2() {
        return new Promise((resolve, reject) => {
            resolve('p2')
        })
    }
    
    Promise.all(['a', 'b', p1(), p2(), 'c']).then(result => console.log(result))
    
    // 结果:两秒钟后打印
    //	["a", "b", "p1", "p2", "c"]
    
  • Promise.all 接收的是一个数组,返回的也是一个Promise 对象。
  • 假如出入所有传入所有Promise 对象返回的结果都是成功的,那么Promise.all 返回的结果也是成功的。
  • 假如出入所有传入所有Promise 对象返回的结果其中一个是失败的,那么Promise.all 返回的结果是失败的。

实现 Promise.all 方法基本示例:

	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
   		... 这部分代码没修改 ...
    	
   	   	static all (array) {
	        // 声明一个结果数组
	        let result = []
	        // 结果数组添加结果方法
	        function addData (key, value) {
	            result[key] = value
	        }
	        // 返回 Promise 对象
	        return new MyPromise((resolve, reject) => {
	            // 遍历传进来的数组
	            for (let i = 0; i < array.length; i++) {
	                // 获取数组当前的值
	                let current = array[i];
	                // 判断当前的值是否为 Promise 对象
	                if (current instanceof MyPromise) {
	                    // Promise 对象
	                    current.then(value => addData(i, value), reason => reject(reason))
	                } else {
	                    // 普通值,直接添加到结果数组中
	                    addData(i, current)
	                }
	            }
	            resolve(result)
	        })
	    }
	}
	function resolvePromise (promise2, x, resolve, reject) {
   		... 这部分代码没修改 ...
	}
	
	// 测试:
	function p1 () {
	    return new MyPromise((resolve, reject) => {
	        setTimeout(() => resolve('p1'), 2000)
	    })
	}
	
	function p2 () {
	    return new MyPromise((resolve, reject) => {
	        resolve('p2')
	    })
	}
	MyPromise.all(['a', 'b', p1(), p2(), 'c']).then(result => console.log(result))
	
  	// 结果:直接打印
    //	['a', 'b', <1 empty item>, 'p2', 'c']
    // 预想结果: 两秒钟后打印
    //  ['a', 'b', 'p1', 'p2', 'c']
    
  • 返回结果有一个空值(<1 empty item>)

原因分析: 执行MyPromise.all 时 执行 for 循环期间 p1 是异步操作的,循环是没有等待异步操作的,直接调用 resolve(result) ,这是 p1 的结果还没出来,所以会有一个 空值

实现 Promise.all 方法完整示例

	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
	    constructor(executor) {
	        try {
	            // 执行器传进来,立即执行
	            executor(this.resolve, this.reject)
	        } catch (e) {
	            this.reject(e)
	        }
	    }
	    // 状态,初始为pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 没有
	    value = undefined
	    // 保存失败的值,默认 没有
	    reason = undefined
	    // 保存成功回调
	    successCallBack = []
	    // 保存失败回调
	    failCallBack = []
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	        // 判断成功回调是否存在
	        // this.successCallBack && this.successCallBack(this.value)
	        // while (this.successCallBack.length) this.successCallBack.shift()(this.value)
	        while (this.successCallBack.length) this.successCallBack.shift()()
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	        // 判断失败回调是否存在
	        // this.failCallBack && this.failCallBack(this.reason)
	        // while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
	        while (this.failCallBack.length) this.failCallBack.shift()()
	    }
	
	    then = (successCallBack, failCallBack) => {
	        // 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
	        successCallBack = successCallBack ? successCallBack : value => value
	        failCallBack = failCallBack ? failCallBack : reason => { throw reason }
	        // 实现then 方法返回一个promise对象
	        let promise2 = new MyPromise((resolve, reject) => {
	            // successCallBack, failCallBack 是function
	            if (this.status === FULFILLED) {
	                // 把这部分的代码变成异步,才能正常获取promise2
	                setTimeout(() => {
	                    try {
	                        // 状态为成功,调用成功回调函数
	                        let x = successCallBack(this.value)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else if (this.status === REJECTED) {
	                setTimeout(() => {
	                    try {
	                        // 状态为失败,调用失败回调函数
	                        failCallBack(this.reason)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else {
	                // 状态为等待
	                // 将成功回调、失败回调 存储起来
	                this.successCallBack.push(() => {
	                    // successCallBack()
	                    setTimeout(() => {
	                        try {
	                            // 状态为成功,调用成功回调函数
	                            let x = successCallBack(this.value)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	                this.failCallBack.push(() => {
	                    setTimeout(() => {
	                        // failCallBack()
	                        try {
	                            // 状态为失败,调用失败回调函数
	                            failCallBack(this.reason)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	            }
	        })
	        return promise2
	    }
	
	    static all (array) {
	        // 声明一个结果数组
	        let result = []
	        let index = 0
	
	        // 返回 Promise 对象
	        return new MyPromise((resolve, reject) => {
	            // 结果数组添加结果方法
	            function addData (key, value) {
	                result[key] = value
	                index++
	                if (index == array.length) {
	                    // 当结果的长度和传进来的长度相等时才返回所有结果
	                    resolve(result)
	                }
	            }
	            // 遍历传进来的数组
	            for (let i = 0; i < array.length; i++) {
	                // 获取数组当前的值
	                let current = array[i];
	                // 判断当前的值是否为 Promise 对象
	                if (current instanceof MyPromise) {
	                    // Promise 对象
	                    current.then(value => addData(i, value), reason => reject(reason))
	                } else {
	                    // 普通值,直接添加到结果数组中
	                    addData(i, current)
	                }
	            }
	        })
	    }
	}
	
	function 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(value => resolve(value), reason => reject(reason))
	        x.then(resolve, reject)
	    } else {
	        // 普通值
	        resolve(x)
	    }
	}
	
	// 测试一
	function p1 () {
	    return new MyPromise((resolve, reject) => {
	        setTimeout(() => resolve('p1'), 2000)
	    })
	}
	
	function p2 () {
	    return new MyPromise((resolve, reject) => {
	        resolve('p2')
	    })
	}
	MyPromise.all(['a', 'b', p1(), p2(), 'c']).then(result => console.log(result))
	
  	// 结果:直接打印
    //	['a', 'b', 'p1', 'p2', 'c']   
    

十、Promise.resolve 方法的实现

  • Promise.resolve 方法是给指定的值转换成Promsie对象

Promise.resolve 方法示例:

   function p1() {
        return new Promise((resolve, reject) => {
            setTimeout(() => resolve('p1'), 2000)
        })
    }
    Promise.resolve(12).then(result => console.log(result))
    Promise.resolve(p1()).then(result => console.log(result))
        
    // 结果:
    //  12
    // 	p1  // 两秒钟后打印
        

实现 Promise.resolve 方法

        
	const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败

class MyPromise {
    constructor(executor) {
        try {
            // 执行器传进来,立即执行
            executor(this.resolve, this.reject)
        } catch (e) {
            this.reject(e)
        }
    }
    // 状态,初始为pending(等待)
    status = PENDING
    // 保存成功的值,默认 没有
    value = undefined
    // 保存失败的值,默认 没有
    reason = undefined
    // 保存成功回调
    successCallBack = []
    // 保存失败回调
    failCallBack = []

    resolve = value => {
        // 如果不是等待状态,就组织函数继续执行
        if (this.status !== PENDING) return
        // pending(等待) ---> fulfilled(成功)
        this.status = FULFILLED
        // 保存成功的值
        this.value = value
        // 判断成功回调是否存在
        // this.successCallBack && this.successCallBack(this.value)
        // while (this.successCallBack.length) this.successCallBack.shift()(this.value)
        while (this.successCallBack.length) this.successCallBack.shift()()
    }

    reject = reason => {
        // 如果不是等待状态,就组织函数继续执行
        if (this.status !== PENDING) return
        // pending(等待) ---> rejected(失败)
        this.status = REJECTED
        // 保存失败的值
        this.reason = reason
        // 判断失败回调是否存在
        // this.failCallBack && this.failCallBack(this.reason)
        // while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
        while (this.failCallBack.length) this.failCallBack.shift()()
    }

    then = (successCallBack, failCallBack) => {
        // 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
        successCallBack = successCallBack ? successCallBack : value => value
        failCallBack = failCallBack ? failCallBack : reason => { throw reason }
        // 实现then 方法返回一个promise对象
        let promise2 = new MyPromise((resolve, reject) => {
            // successCallBack, failCallBack 是function
            if (this.status === FULFILLED) {
                // 把这部分的代码变成异步,才能正常获取promise2
                setTimeout(() => {
                    try {
                        // 状态为成功,调用成功回调函数
                        let x = successCallBack(this.value)
                        // resolve(x)
                        // 判断 X 的值是普通还是promise对象
                        // 如果是普通值 直接调用resolve
                        // 如果是promise对象 查看promise对象返回结果
                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                        reject(e)
                    }
                }, 0)
            } else if (this.status === REJECTED) {
                setTimeout(() => {
                    try {
                        // 状态为失败,调用失败回调函数
                        failCallBack(this.reason)
                        // resolve(x)
                        // 判断 X 的值是普通还是promise对象
                        // 如果是普通值 直接调用resolve
                        // 如果是promise对象 查看promise对象返回结果
                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                        reject(e)
                    }
                }, 0)
            } else {
                // 状态为等待
                // 将成功回调、失败回调 存储起来
                this.successCallBack.push(() => {
                    // successCallBack()
                    setTimeout(() => {
                        try {
                            // 状态为成功,调用成功回调函数
                            let x = successCallBack(this.value)
                            // resolve(x)
                            // 判断 X 的值是普通还是promise对象
                            // 如果是普通值 直接调用resolve
                            // 如果是promise对象 查看promise对象返回结果
                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (e) {
                            reject(e)
                        }
                    }, 0)
                })
                this.failCallBack.push(() => {
                    setTimeout(() => {
                        // failCallBack()
                        try {
                            // 状态为失败,调用失败回调函数
                            failCallBack(this.reason)
                            // resolve(x)
                            // 判断 X 的值是普通还是promise对象
                            // 如果是普通值 直接调用resolve
                            // 如果是promise对象 查看promise对象返回结果
                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (e) {
                            reject(e)
                        }
                    }, 0)
                })
            }
        })
        return promise2
    }

    static all (array) {
        // 声明一个结果数组
        let result = []
        let index = 0

        // 返回 Promise 对象
        return new MyPromise((resolve, reject) => {
            // 结果数组添加结果方法
            function addData (key, value) {
                result[key] = value
                index++
                if (index == array.length) {
                    // 当结果的长度和传进来的长度相等时才返回所有结果
                    resolve(result)
                }
            }
            // 遍历传进来的数组
            for (let i = 0; i < array.length; i++) {
                // 获取数组当前的值
                let current = array[i];
                // 判断当前的值是否为 Promise 对象
                if (current instanceof MyPromise) {
                    // Promise 对象
                    current.then(value => addData(i, value), reason => reject(reason))
                } else {
                    // 普通值,直接添加到结果数组中
                    addData(i, current)
                }
            }
        })
    }

    static resolve (value) {
        // 是MyPromise对象直接返回的
        if (value instanceof MyPromise) return value
        // 不是对象,创建一个MyPromise,把 resolve(value) 返回
        return new MyPromise(resolve => resolve(value))
    }
}

function 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(value => resolve(value), reason => reject(reason))
        x.then(resolve, reject)
    } else {
        // 普通值
        resolve(x)
    }
}

// 测试一
function p1 () {
    return new MyPromise((resolve, reject) => {
        setTimeout(() => resolve('p1'), 2000)
    })
}

MyPromise.resolve(12).then(result => console.log(result))
MyPromise.resolve(p1()).then(result => console.log(result))

    // 结果:
    //  12
    // 	p1  // 两秒钟后打印

十一、Promise.finally 方法的实现

  • Promise.finally 方法无论当前状态是成功还是失败,走回执行一次
  • Promise.finally 方法可以使用 .then() 拿到当前Promise 对象最终返回的结果

Promise.finally 方法示例:

   function p1() {
        return new Promise((resolve, reject) => {
            setTimeout(() => resolve('p1'), 2000)
        })
    }
    Promise.resolve(12).then(result => console.log(result))
    Promise.resolve(p1()).then(result => console.log(result))
        
    // 结果:
    //  12
    // 	p1  // 两秒钟后打印
        

Promise.finally 方法基本示例:

   
	class MyPromise {
		... 这部分代码没修改 ...
	
	    finally (callback) {
	        // 调用 this.then 获取当前状态
	        // this.then(() => { callback() }, () => { callback() })
	        // finally 返回的也是 Promise 对象
	        return this.then(value => {
	            callback()
	            return value
	        }, reason => {
	            callback()
	            throw reason
	        })
	    }
		
	}
	// 测试
	function p1 () {
	    return new MyPromise((resolve, reject) => {
	        setTimeout(() => resolve('p1'), 2000)
	    })
	}
	
	function p2 () {
	    return new MyPromise((resolve, reject) => {
	        resolve('p2 resolve')
	        // reject('p2 reject')
	    })
	}
	
	p2().finally(() => {
	    console.log('finally');
	    // return p1()
	}).then(value => console.log(value), reason => console.log(reason))
        
    // 结果:
    //  finally
	//  p2 resolve
    // finally 里面 return p1() ,直接打印结果,没有延迟两秒钟
   	//  finally
	//  p2 resolve
    

实现 Promise.finally 方法完整示例


	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
	    constructor(executor) {
	        try {
	            // 执行器传进来,立即执行
	            executor(this.resolve, this.reject)
	        } catch (e) {
	            this.reject(e)
	        }
	    }
	    // 状态,初始为pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 没有
	    value = undefined
	    // 保存失败的值,默认 没有
	    reason = undefined
	    // 保存成功回调
	    successCallBack = []
	    // 保存失败回调
	    failCallBack = []
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	        // 判断成功回调是否存在
	        // this.successCallBack && this.successCallBack(this.value)
	        // while (this.successCallBack.length) this.successCallBack.shift()(this.value)
	        while (this.successCallBack.length) this.successCallBack.shift()()
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	        // 判断失败回调是否存在
	        // this.failCallBack && this.failCallBack(this.reason)
	        // while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
	        while (this.failCallBack.length) this.failCallBack.shift()()
	    }
	
	    then = (successCallBack, failCallBack) => {
	        // 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
	        successCallBack = successCallBack ? successCallBack : value => value
	        failCallBack = failCallBack ? failCallBack : reason => { throw reason }
	        // 实现then 方法返回一个promise对象
	        let promise2 = new MyPromise((resolve, reject) => {
	            // successCallBack, failCallBack 是function
	            if (this.status === FULFILLED) {
	                // 把这部分的代码变成异步,才能正常获取promise2
	                setTimeout(() => {
	                    try {
	                        // 状态为成功,调用成功回调函数
	                        let x = successCallBack(this.value)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else if (this.status === REJECTED) {
	                setTimeout(() => {
	                    try {
	                        // 状态为失败,调用失败回调函数
	                        failCallBack(this.reason)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else {
	                // 状态为等待
	                // 将成功回调、失败回调 存储起来
	                this.successCallBack.push(() => {
	                    // successCallBack()
	                    setTimeout(() => {
	                        try {
	                            // 状态为成功,调用成功回调函数
	                            let x = successCallBack(this.value)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	                this.failCallBack.push(() => {
	                    setTimeout(() => {
	                        // failCallBack()
	                        try {
	                            // 状态为失败,调用失败回调函数
	                            failCallBack(this.reason)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	            }
	        })
	        return promise2
	    }
	
	    finally (callback) {
	        // 调用 this.then 获取当前状态
	        // this.then(() => { callback() }, () => { callback() })
	        // finally 返回的也是 Promise 对象
	        return this.then(value => {
	            // callback()
	            // return value
	            return MyPromise.resolve(callback()).then(() => value)
	        }, reason => {
	            // callback()
	            // throw reason
	            return MyPromise.reject(callback()).then(() => { throw reason })
	        })
	    }
	
	    static all (array) {
	        // 声明一个结果数组
	        let result = []
	        let index = 0
	
	        // 返回 Promise 对象
	        return new MyPromise((resolve, reject) => {
	            // 结果数组添加结果方法
	            function addData (key, value) {
	                result[key] = value
	                index++
	                if (index == array.length) {
	                    // 当结果的长度和传进来的长度相等时才返回所有结果
	                    resolve(result)
	                }
	            }
	            // 遍历传进来的数组
	            for (let i = 0; i < array.length; i++) {
	                // 获取数组当前的值
	                let current = array[i];
	                // 判断当前的值是否为 Promise 对象
	                if (current instanceof MyPromise) {
	                    // Promise 对象
	                    current.then(value => addData(i, value), reason => reject(reason))
	                } else {
	                    // 普通值,直接添加到结果数组中
	                    addData(i, current)
	                }
	            }
	        })
	    }
	
	    static resolve (value) {
	        // 是MyPromise对象直接返回的
	        if (value instanceof MyPromise) return value
	        // 不是对象,创建一个MyPromise,把 resolve(value) 返回
	        return new MyPromise(resolve => resolve(value))
	    }
	}
	
	function 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(value => resolve(value), reason => reject(reason))
	        x.then(resolve, reject)
	    } else {
	        // 普通值
	        resolve(x)
	    }
	}
	
	// 测试
	function p1 () {
	    return new MyPromise(function (resolve, reject) {
	        setTimeout(function () {
	            resolve('p1')
	        }, 2000)
	    })
	}
	
	function p2 () {
	    return new MyPromise((resolve, reject) => {
	        resolve('p2 resolve')
	        // reject('p2 reject')
	    })
	}
	
	p2().finally(() => {
	    console.log('finally');
	    return p1()
	}).then(value => console.log(value), reason => console.log(reason))
	
	// 结果:
	// finally 里面 return p1() 两秒钟后打印
   	//  finally
	//  p2 resolve

十二、Promise.catch 方法的实现

Promise.catch 方法示例:

    let promise = new Promise((resolve, reject) => {
        // setTimeout(() => resolve('成功'), 2000)
        reject('失败')
    });
    promise.catch(reason => console.log(reason))
        
    // 结果:
    //  失败
        

实现 Promise.catch 方法


	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
	    constructor(executor) {
	        try {
	            // 执行器传进来,立即执行
	            executor(this.resolve, this.reject)
	        } catch (e) {
	            this.reject(e)
	        }
	    }
	    // 状态,初始为pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 没有
	    value = undefined
	    // 保存失败的值,默认 没有
	    reason = undefined
	    // 保存成功回调
	    successCallBack = []
	    // 保存失败回调
	    failCallBack = []
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	        // 判断成功回调是否存在
	        // this.successCallBack && this.successCallBack(this.value)
	        // while (this.successCallBack.length) this.successCallBack.shift()(this.value)
	        while (this.successCallBack.length) this.successCallBack.shift()()
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	        // 判断失败回调是否存在
	        // this.failCallBack && this.failCallBack(this.reason)
	        // while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
	        while (this.failCallBack.length) this.failCallBack.shift()()
	    }
	
	    then = (successCallBack, failCallBack) => {
	        // 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
	        successCallBack = successCallBack ? successCallBack : value => value
	        failCallBack = failCallBack ? failCallBack : reason => { throw reason }
	        // 实现then 方法返回一个promise对象
	        let promise2 = new MyPromise((resolve, reject) => {
	            // successCallBack, failCallBack 是function
	            if (this.status === FULFILLED) {
	                // 把这部分的代码变成异步,才能正常获取promise2
	                setTimeout(() => {
	                    try {
	                        // 状态为成功,调用成功回调函数
	                        let x = successCallBack(this.value)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else if (this.status === REJECTED) {
	                setTimeout(() => {
	                    try {
	                        // 状态为失败,调用失败回调函数
	                        failCallBack(this.reason)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else {
	                // 状态为等待
	                // 将成功回调、失败回调 存储起来
	                this.successCallBack.push(() => {
	                    // successCallBack()
	                    setTimeout(() => {
	                        try {
	                            // 状态为成功,调用成功回调函数
	                            let x = successCallBack(this.value)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	                this.failCallBack.push(() => {
	                    setTimeout(() => {
	                        // failCallBack()
	                        try {
	                            // 状态为失败,调用失败回调函数
	                            failCallBack(this.reason)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	            }
	        })
	        return promise2
	    }
	
	    finally (callback) {
	        // 调用 this.then 获取当前状态
	        // this.then(() => { callback() }, () => { callback() })
	        // finally 返回的也是 Promise 对象
	        return this.then(value => {
	            // callback()
	            // return value
	            return MyPromise.resolve(callback()).then(() => value)
	        }, reason => {
	            // callback()
	            // throw reason
	            return MyPromise.reject(callback()).then(() => { throw reason })
	        })
	    }
	
	    catch (failCallBack) {
	        return this.then(undefined, failCallBack)
	    }
	
	    static all (array) {
	        // 声明一个结果数组
	        let result = []
	        let index = 0
	
	        // 返回 Promise 对象
	        return new MyPromise((resolve, reject) => {
	            // 结果数组添加结果方法
	            function addData (key, value) {
	                result[key] = value
	                index++
	                if (index == array.length) {
	                    // 当结果的长度和传进来的长度相等时才返回所有结果
	                    resolve(result)
	                }
	            }
	            // 遍历传进来的数组
	            for (let i = 0; i < array.length; i++) {
	                // 获取数组当前的值
	                let current = array[i];
	                // 判断当前的值是否为 Promise 对象
	                if (current instanceof MyPromise) {
	                    // Promise 对象
	                    current.then(value => addData(i, value), reason => reject(reason))
	                } else {
	                    // 普通值,直接添加到结果数组中
	                    addData(i, current)
	                }
	            }
	        })
	    }
	
	    static resolve (value) {
	        // 是MyPromise对象直接返回的
	        if (value instanceof MyPromise) return value
	        // 不是对象,创建一个MyPromise,把 resolve(value) 返回
	        return new MyPromise(resolve => resolve(value))
	    }
	}
	
	function 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(value => resolve(value), reason => reject(reason))
	        x.then(resolve, reject)
	    } else {
	        // 普通值
	        resolve(x)
	    }
	}
	
	// 测试
	function p2 () {
	    return new MyPromise((resolve, reject) => {
	        // resolve('p2 resolve')
	        reject('p2 reject')
	    })
	}
	
	p2().then(value => console.log(value)).catch(reason => console.log('catch ', reason))

    // 结果:
    //  catch  p2 reject

十三、Promise.reject 方法的实现

Promise reject 方法示例:

	Promise.resolve(12).then(result => console.log(result))
    
    // 结果:
    //	12
    

实现 Promise reject 方法


const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败

class MyPromise {
    constructor(executor) {
        try {
            // 执行器传进来,立即执行
            executor(this.resolve, this.reject)
        } catch (e) {
            this.reject(e)
        }
    }
    // 状态,初始为pending(等待)
    status = PENDING
    // 保存成功的值,默认 没有
    value = undefined
    // 保存失败的值,默认 没有
    reason = undefined
    // 保存成功回调
    successCallBack = []
    // 保存失败回调
    failCallBack = []

    resolve = value => {
        // 如果不是等待状态,就组织函数继续执行
        if (this.status !== PENDING) return
        // pending(等待) ---> fulfilled(成功)
        this.status = FULFILLED
        // 保存成功的值
        this.value = value
        // 判断成功回调是否存在
        // this.successCallBack && this.successCallBack(this.value)
        // while (this.successCallBack.length) this.successCallBack.shift()(this.value)
        while (this.successCallBack.length) this.successCallBack.shift()()
    }

    reject = reason => {
        // 如果不是等待状态,就组织函数继续执行
        if (this.status !== PENDING) return
        // pending(等待) ---> rejected(失败)
        this.status = REJECTED
        // 保存失败的值
        this.reason = reason
        // console.log('this.reason', this.reason);
        // 判断失败回调是否存在
        // this.failCallBack && this.failCallBack(this.reason)
        // while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
        while (this.failCallBack.length) this.failCallBack.shift()()
    }

    then = (successCallBack, failCallBack) => {
        // 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
        successCallBack = successCallBack ? successCallBack : value => value
        failCallBack = failCallBack ? failCallBack : reason => { throw reason }
        // 实现then 方法返回一个promise对象
        let promise2 = new MyPromise((resolve, reject) => {
            // successCallBack, failCallBack 是function
            if (this.status === FULFILLED) {
                // 把这部分的代码变成异步,才能正常获取promise2
                setTimeout(() => {
                    try {
                        // 状态为成功,调用成功回调函数
                        let x = successCallBack(this.value)
                        // resolve(x)
                        // 判断 X 的值是普通还是promise对象
                        // 如果是普通值 直接调用resolve
                        // 如果是promise对象 查看promise对象返回结果
                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                        reject(e)
                    }
                }, 0)
            } else if (this.status === REJECTED) {
                setTimeout(() => {
                    try {
                        // 状态为失败,调用失败回调函数
                        failCallBack(this.reason)
                        // resolve(x)
                        // 判断 X 的值是普通还是promise对象
                        // 如果是普通值 直接调用resolve
                        // 如果是promise对象 查看promise对象返回结果
                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                        reject(e)
                    }
                }, 0)
            } else {
                // 状态为等待
                // 将成功回调、失败回调 存储起来
                this.successCallBack.push(() => {
                    // successCallBack()
                    setTimeout(() => {
                        try {
                            // 状态为成功,调用成功回调函数
                            let x = successCallBack(this.value)
                            // resolve(x)
                            // 判断 X 的值是普通还是promise对象
                            // 如果是普通值 直接调用resolve
                            // 如果是promise对象 查看promise对象返回结果
                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (e) {
                            reject(e)
                        }
                    }, 0)
                })
                this.failCallBack.push(() => {
                    setTimeout(() => {
                        // failCallBack()
                        try {
                            // 状态为失败,调用失败回调函数
                            failCallBack(this.reason)
                            // resolve(x)
                            // 判断 X 的值是普通还是promise对象
                            // 如果是普通值 直接调用resolve
                            // 如果是promise对象 查看promise对象返回结果
                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (e) {
                            reject(e)
                        }
                    }, 0)
                })
            }
        })
        return promise2
    }

    finally (callback) {
        // 调用 this.then 获取当前状态
        // this.then(() => { callback() }, () => { callback() })
        // finally 返回的也是 Promise 对象
        return this.then(value => {
            // callback()
            // return value
            return MyPromise.resolve(callback()).then(() => value)
        }, reason => {
            // callback()
            // throw reason
            return MyPromise.reject(callback()).then(() => { throw reason })
        })
    }

    catch (failCallBack) {
        return this.then(undefined, failCallBack)
    }

    static all (array) {
        // 声明一个结果数组
        let result = []
        let index = 0

        // 返回 Promise 对象
        return new MyPromise((resolve, reject) => {
            // 结果数组添加结果方法
            function addData (key, value) {
                result[key] = value
                index++
                if (index == array.length) {
                    // 当结果的长度和传进来的长度相等时才返回所有结果
                    resolve(result)
                }
            }
            // 遍历传进来的数组
            for (let i = 0; i < array.length; i++) {
                // 获取数组当前的值
                let current = array[i];
                // 判断当前的值是否为 Promise 对象
                if (current instanceof MyPromise) {
                    // Promise 对象
                    current.then(value => addData(i, value), reason => reject(reason))
                } else {
                    // 普通值,直接添加到结果数组中
                    addData(i, current)
                }
            }
        })
    }

    static resolve (value) {
        // 是MyPromise对象直接返回的
        if (value instanceof MyPromise) return value
        // 不是对象,创建一个MyPromise,把 resolve(value) 返回
        return new MyPromise(resolve => resolve(value))
    }

    static reject (reason) {
        // 是MyPromise对象直接返回的
        if (reason instanceof MyPromise) {
            console.log(reason);
            return reason
        }
        // 不是对象,创建一个MyPromise,把 reject(reason) 返回
        return new MyPromise((resolve, reject) => {
            reject(reason)
        })
    }
}

function 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(value => resolve(value), reason => reject(reason))
        x.then(resolve, reject)
    } else {
        // 普通值
        resolve(x)
    }
}

// 测试
function p1 () {
    return new MyPromise((resolve, reject) => {
        setTimeout(() => resolve('p1'), 2000)
    })
}
MyPromise.reject(12).catch(reason => console.log(reason))
// MyPromise.reject(p1()).then(result => console.log(result))

// 结果
//  12

十四、Promise.race 方法的实现


	const PENDING = 'pending' // 等待
	const FULFILLED = 'fulfilled' // 成功
	const REJECTED = 'rejected' // 失败
	
	class MyPromise {
	    constructor(executor) {
	        try {
	            // 执行器传进来,立即执行
	            executor(this.resolve, this.reject)
	        } catch (e) {
	            this.reject(e)
	        }
	    }
	    // 状态,初始为pending(等待)
	    status = PENDING
	    // 保存成功的值,默认 没有
	    value = undefined
	    // 保存失败的值,默认 没有
	    reason = undefined
	    // 保存成功回调
	    successCallBack = []
	    // 保存失败回调
	    failCallBack = []
	
	    resolve = value => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> fulfilled(成功)
	        this.status = FULFILLED
	        // 保存成功的值
	        this.value = value
	        // 判断成功回调是否存在
	        // this.successCallBack && this.successCallBack(this.value)
	        // while (this.successCallBack.length) this.successCallBack.shift()(this.value)
	        while (this.successCallBack.length) this.successCallBack.shift()()
	    }
	
	    reject = reason => {
	        // 如果不是等待状态,就组织函数继续执行
	        if (this.status !== PENDING) return
	        // pending(等待) ---> rejected(失败)
	        this.status = REJECTED
	        // 保存失败的值
	        this.reason = reason
	        // console.log('this.reason', this.reason);
	        // 判断失败回调是否存在
	        // this.failCallBack && this.failCallBack(this.reason)
	        // while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
	        while (this.failCallBack.length) this.failCallBack.shift()()
	    }
	
	    then = (successCallBack, failCallBack) => {
	        // 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
	        successCallBack = successCallBack ? successCallBack : value => value
	        failCallBack = failCallBack ? failCallBack : reason => { throw reason }
	        // 实现then 方法返回一个promise对象
	        let promise2 = new MyPromise((resolve, reject) => {
	            // successCallBack, failCallBack 是function
	            if (this.status === FULFILLED) {
	                // 把这部分的代码变成异步,才能正常获取promise2
	                setTimeout(() => {
	                    try {
	                        // 状态为成功,调用成功回调函数
	                        let x = successCallBack(this.value)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else if (this.status === REJECTED) {
	                setTimeout(() => {
	                    try {
	                        // 状态为失败,调用失败回调函数
	                        failCallBack(this.reason)
	                        // resolve(x)
	                        // 判断 X 的值是普通还是promise对象
	                        // 如果是普通值 直接调用resolve
	                        // 如果是promise对象 查看promise对象返回结果
	                        // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                        resolvePromise(promise2, x, resolve, reject)
	                    } catch (e) {
	                        reject(e)
	                    }
	                }, 0)
	            } else {
	                // 状态为等待
	                // 将成功回调、失败回调 存储起来
	                this.successCallBack.push(() => {
	                    // successCallBack()
	                    setTimeout(() => {
	                        try {
	                            // 状态为成功,调用成功回调函数
	                            let x = successCallBack(this.value)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	                this.failCallBack.push(() => {
	                    setTimeout(() => {
	                        // failCallBack()
	                        try {
	                            // 状态为失败,调用失败回调函数
	                            failCallBack(this.reason)
	                            // resolve(x)
	                            // 判断 X 的值是普通还是promise对象
	                            // 如果是普通值 直接调用resolve
	                            // 如果是promise对象 查看promise对象返回结果
	                            // 在根据promise对象返回的结果 决定调用resolve 还是reject
	                            resolvePromise(promise2, x, resolve, reject)
	                        } catch (e) {
	                            reject(e)
	                        }
	                    }, 0)
	                })
	            }
	        })
	        return promise2
	    }
	
	    finally (callback) {
	        // 调用 this.then 获取当前状态
	        // this.then(() => { callback() }, () => { callback() })
	        // finally 返回的也是 Promise 对象
	        return this.then(value => {
	            // callback()
	            // return value
	            return MyPromise.resolve(callback()).then(() => value)
	        }, reason => {
	            // callback()
	            // throw reason
	            return MyPromise.reject(callback()).then(() => { throw reason })
	        })
	    }
	
	    catch (failCallBack) {
	        return this.then(undefined, failCallBack)
	    }
	
	    static all (array) {
	        // 声明一个结果数组
	        let result = []
	        let index = 0
	
	        // 返回 Promise 对象
	        return new MyPromise((resolve, reject) => {
	            // 结果数组添加结果方法
	            function addData (key, value) {
	                result[key] = value
	                index++
	                if (index == array.length) {
	                    // 当结果的长度和传进来的长度相等时才返回所有结果
	                    resolve(result)
	                }
	            }
	            // 遍历传进来的数组
	            for (let i = 0; i < array.length; i++) {
	                // 获取数组当前的值
	                let current = array[i];
	                // 判断当前的值是否为 Promise 对象
	                if (current instanceof MyPromise) {
	                    // Promise 对象
	                    current.then(value => addData(i, value), reason => reject(reason))
	                } else {
	                    // 普通值,直接添加到结果数组中
	                    addData(i, current)
	                }
	            }
	        })
	    }
	
	    static resolve (value) {
	        // 是MyPromise对象直接返回的
	        if (value instanceof MyPromise) return value
	        // 不是对象,创建一个MyPromise,把 resolve(value) 返回
	        return new MyPromise(resolve => resolve(value))
	    }
	
	    static reject (reason) {
	        // 是MyPromise对象直接返回的
	        if (reason instanceof MyPromise) {
	            console.log(reason);
	            return reason
	        }
	        // 不是对象,创建一个MyPromise,把 reject(reason) 返回
	        return new MyPromise((resolve, reject) => {
	            reject(reason)
	        })
	    }
	
	    static race (array) {
	        // 声明一个结果
	        let result = undefined
	
	        // 返回 Promise 对象
	        return new MyPromise((resolve, reject) => {
	            // 结果数组添加结果方法
	            function addData (value) {
	                result = value
	                if (result) {
	                    // 当结果不为空的时候的就返回
	                    resolve(result)
	                }
	            }
	            // 遍历传进来的数组
	            for (let i = 0; i < array.length; i++) {
	                // 获取数组当前的值
	                let current = array[i];
	                // 判断当前的值是否为 Promise 对象
	                if (current instanceof MyPromise) {
	                    // Promise 对象
	                    current.then(value => addData(value), reason => reject(reason))
	                } else {
	                    // 普通值,直接添加到结果数组中
	                    addData(current)
	                }
	            }
	        })
	    }
	}
	
	function 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(value => resolve(value), reason => reject(reason))
	        x.then(resolve, reject)
	    } else {
	        // 普通值
	        resolve(x)
	    }
	}
	
	// 测试
	function p1 () {
	    return new MyPromise((resolve, reject) => {
	        setTimeout(() => resolve('p1'), 2000)
	    })
	}
	
	function p2 () {
	    return new MyPromise((resolve, reject) => {
	        // resolve('p2')
	        reject('p2')
	    })
	}
	MyPromise.race([p1(), p2()]).then(result => console.log(result)).catch(reason => console.log(reason))

	// 结果
	//  p2

总结

通过手写实现 Promise,增加对 Promise 的了解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值