ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

手写Promise代码 逻辑注释

2020-11-30 23:59:20  阅读:228  来源: 互联网

标签:resolve reason value 注释 fcb Promise reject 手写


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有