其他分享
首页 > 其他分享> > 手写Promise代码 逻辑注释

手写Promise代码 逻辑注释

作者:互联网

Promise代码

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
    // 因为状态经常使用所以设置为常量

function resolvePromise(Promise2, x, resolve, reject) {
    if (Promise2 === x) { //防止Promise重复调用
        reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    if (x instanceof MyPromise) {
        x.then(resolve, reject)
    } else {
        resolve(x)
    }
}
class MyPromise {

    //传进执行器,执行器立即执行
    constructor(executor) {
            executor(this.resolve, this.reject)
        }
        //Promise的状态
    status = PENDING
        //成功的值
    value = undefined
        //失败的值
    reason = undefined

    scb = []

    fcb = []
        //箭头函数使this指向指向当前Mypromise
    resolve = value => {

        if (this.status != PENDING) return
        this.status = FULFILLED
            //保存成功之后的值
        this.value = value
        while (this.scb.length) this.scb.shift()()
    }
    reject = reason => {
        if (this.status != PENDING) return
        this.status = REJECTED
            //保存失败之后的值
        this.reason = reason
            // this.fcb && this.fcb(reason)
        while (this.fcb.length) this.fcb.shift()()
    }
    then(scb, fcb) {
        scb = scb ? scb : value => value; //使then方法的参数变为可选参数
        fcb = fcb ? fcb : reason => { throw reason };
        let Promise2 = new MyPromise((resolve, reject) => {
            if (this.status === FULFILLED) {
                setTimeout(() => { //使用setTimeOut来拿到Promise的值
                    try { //用来捕获错误
                        let x = scb(this.value)
                            // 判断x值是普通值还是myPromise对象,分别做处理。
                            // 因为三个判断都需要可以抽取为一个函数
                        resolvePromise(Promise2, x, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                }, 0)
            } else if (this.status === REJECTED) {
                setTimeout(() => { //使用setTimeOut来拿到Promise的值
                        try { //用来捕获错误
                            let x = fcb(this.reason)
                                // 判断x值是普通值还是myPromise对象,分别做处理。
                                // 因为三个判断都需要可以抽取为一个函数
                            resolvePromise(Promise2, x, resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                    }, 0)
                    // let x = fcb(this.reason)
                    // reject(x)
            } else {
                //等待 存储回调
                // this.fcb = fcb;
                // this.scb = scb;
                this.scb.push(() => {
                    setTimeout(() => { //使用setTimeOut来拿到Promise的值
                        try { //用来捕获错误
                            let x = scb(this.value)
                                // 判断x值是普通值还是myPromise对象,分别做处理。
                                // 因为三个判断都需要可以抽取为一个函数
                            resolvePromise(Promise2, x, resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                    }, 0)
                });
                this.fcb.push(() => {
                    setTimeout(() => { //使用setTimeOut来拿到Promise的值
                        try { //用来捕获错误
                            let x = fcb(this.reason)
                                // 判断x值是普通值还是myPromise对象,分别做处理。
                                // 因为三个判断都需要可以抽取为一个函数
                            resolvePromise(Promise2, x, resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                    }, 0)
                });
            }
        })
        return Promise2
    }
    static all(array) {
        let result = [];
        let index = 0; //解决空值,因为要等待异步操作的结果
        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]
                if (current instanceof MyPromise) {
                    //是Promise对象
                    // addData(i, current.then())
                    current.then(value => addData(i, value), reason => reject(reason))
                } else {
                    //是普通值
                }
            }
        })
    }
    static resolve(value) {
        if (value instanceof MyPromise) return value
        return new MyPromise(resolve => resolve(value))
    }
    catch (fcb) {
        return this.then(undefined, fcb)
    } finally(callback) {
        return this.then(value => {
            //调用Mypromise.resolve是等待上一个执行完成
            return MyPromise.resolve(callback()).then(() => value)
        }, reason => {
            return MyPromise.resolve(callback()).then(reason => { throw reason })
        })
    }
}
module.exports = MyPromise;
// module.exprots = MyPromise;

逻辑与步骤

/**
 * ——————————核心逻辑——————————
 * 1.Promise是一个类 在执行这个类的时候,需要传递一个执行器,执行器会立即执行
 * 2.Promise三种状态 pending fulfilled rejected pending
 * pending->fulfilled
 * pending->rejected
 * 3.Promise 中resolve和reject来更改状态
 * 4.then 方法内部判断,then方法应该是被定义原型对象上
 * 5.需要存储成功或者失败的原因
 * ————————————异步逻辑————————————————
 * -then方法存储值,resolve和reject来判断是否有值
 * 存储失败回调和成功回调存储起来
 * ————————————多次调用then————————————
 * 将存储的属性变为一个数组
 * ————————————链式调用——————————————
 * then方法返回的是一个myPromise对象,并需要判段传进的是Mypromise对象或者普通值
 *  then方法链式调用并识别Promise对象自返回(防止Promise的循环调用)
 * ————————————捕获错误——————————————
 * 1,try catch
 * 2.setTimeout  来拿到当前实例返回结果
 * 
 * ————————————then可选参数——————————
 * then方法中判断
 * ————————————myPromise.all方法的实现————————
 * 1.传入一个数组。元素有Promise 和普通值
 * 2.有一个失败最终都失败
 * 3.all方法是静态方法
 * 4.等待异步操作结果,防止空值现象
 * ————————————myPromise.resolve()——————
 * 将一个值转换为Promise 对象 如果是Promise对象直接返回该对象
 * ————————————Promise。fianlly方法——————
 * 无论成功失败,finally方法都会调用
 * 处理下一个等待上一个执行完成
 */

 

标签:resolve,reason,value,注释,fcb,Promise,reject,手写
来源: https://blog.csdn.net/q918922703_1/article/details/110411476