临场发挥--实现手写promise



class Promise1 {

    // promise/A+ 规范:promise状态返回fulfilled(成功),返回的是一个不可以改变的value
    // promise/A+ 规范:promise状态返回rejected(失败),返回的是一个不可以改变的reason
    // promise/A+ 规范:判断状态是否为pending 是pending才可以进行状态改变

    // 2.此时传入一个匿名函数 这时候executor就是这个匿名函数 我们去看 try catch部分 ↓
    constructor(executor) {
        // 初始化的状态
        this.state = 'pending'

        // 成功的值
        this.value = undefined
        // 失败的值
        this.reason = undefined

        // 成功存放的数组
        this.onResolvedCallbacks = [];
        // 失败存放的数组
        this.onRejectedCallbacks = [];


        // 成功 
        let resolve = (value) => {
            if (this.state == 'pending') {
                this.state = 'fulfilled'
                this.value = value
                // 一旦resolve 执行, 调用成功数组的函数
                this.onResolvedCallbacks.forEach(fn => fn());
            }
        }
        // 失败
        let reject = (reason) => {
            if (this.state == 'pending') {
                this.state = 'rejected'
                this.reason = reason
                // 一旦 resolve执行 , 调用失败数组的函数
                this.onRejectedCallbacks.forEach(fn => fn());
            }
        }

        // (resolve, reject) => {
        //     resolve('1')        相当于=========>  
        // })

        // executor = (resolve, reject) => {
        //          resolve('1')   
        //      })

        // 执行 如果executor执行出错,执行catch的reject失败
        try {

            // 执行这个函数 executor()
            // 3.往这个匿名函数传入上面定义的成功和失败的resolve 和 reject的方法 作为参数 executor(resolve, reject)
            executor(resolve, reject)
        } catch{
            reject(err)
        }
    }

    // then方法
    // onFulfilled,onRejected分别是一个函数 
    // 如果状态为fulfilled 执行 onFulfilled ,传入成功的value
    // 如果失败,传入onRejected,传入失败的reason

    // 链式调用, new Promise().then().then(),这就是链式调用
    // 为了达成链式 , 我们默认在第一个then里返回一个Promise. 规定 : 在then里面返回一个新的Promise , 称为promise2;
    // promise2 = new Promise((resolve,reject)=>{})
    // 规定 : onFulfilled()或 onRejected()的值 , 即第一个then返回的值 , 叫做 x ,判断 x 的函数叫做 resolvePromise

    then(onFulfilled, onRejected) {

        // onFulfilled 如果不是函数 , 就忽略 onFulfilled , 直接返回 value
        onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;

        // onRejected 如果不是函数 , 就忽略 onRejected , 直接扔出错误
        onRejected = typeof onRejected === "function" ? onRejected : err => { throw err };

        // 声明返回的 promise2
        // 规定 : 一段代码 , 让不同的promise代码互相套用 , 叫做resolvePromise
        let promise2 = new Promise1((resolve, reject) => {


            // 状态为 fulfilled , 执行 onFulfiiled , 传入成功的值
            if (this.state == 'fulfilled') {

                // 规定 onFulfilled 或 onRejected 不能同步被调用,必须异步调用。我们就用 setTimeout解决异步问题
                setTimeout(() => {
                    try {
                        let x = onFulfilled(this.value);
                        // resolvePromise函数 , 处理自己return 的promise和默认的promise2的关系
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                }, 0)
            }

            //状态为 rejected , 执行onRejected , 传入失败的原因
            if (this.state === 'rejected') {
                //异步
                setTimeout(() => {
                    // 如果报错
                    try {
                        let x = onRejected(this.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                }, 0);
            };


            // 当状态为 pending时
            if (this.state === 'pending') {
                // onFulfilled 传入到成功数组中

                this.onResolvedCallbacks.push(() => {

                    //异步
                    setTimeout(() => {
                        try {
                            let x = onFulfilled(this.value);


                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e)
                        }
                    }, 0);
                })
                // onRejected 传入到失败数组
                this.onRejectedCallbacks.push(() => {
                    // 异步
                    setTimeout(() => {
                        try {
                            let x = onRejected(this.reason);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e)
                        }
                    }, 0)
                })
            }

        })
        // 返回promise2 , 完成链式
        return promise2
    }


    catch(fn) {
        return this.then(null, fn)
    }
}

function resolvePromise(promise2, x, resolve, reject) {


    if (x === promise2) {
        return reject(new TypeError("Chaining cycle detected for promise"));
    }
    // 防止多次调用
    let called;
    // x 不是 null 并且 x 是对象或者函数
    if (x != null && (typeof x === 'object' || typeof x === 'function')) {
        try {
            // A+ 规定 , 声明 then = x 的then 方法
            let then = x.then;
            // 如果 then 是函数 , 就默认是 promise了
            if (typeof then === 'function') {
                // 就让 then 执行 第一个参数是 this 后面是成功的回调和 失败的回调
                then.call(x, y => {
                    // 成功和失败只能调用一个
                    if (called) return;
                    called = true;
                    // resolve 的结果依旧是 promise 那就继续解析
                    resolvePromise(promise2, y, resolve, reject);
                }, err => {
                    // 成功和失败只能调用一个
                    if (called) return;
                    called = true;
                    reject(err); // 失败了就失败了
                })
            } else {
                resolve(x); //直接成功即可
            }
        } catch (e) {
            // 也属于失败
            if (called) return;
            called = true;
            // 取then出错了 那就不要再继续执行了
            reject(e);
        }
    } else {
        resolve(x);
    }
}


// 1.promise里实例化的是一个匿名函数 往consturtor那里看 ↑
let b = new Promise1((resolve, reject) => {
    // 4.拿出回调出来的方法
    reject('error')

})
b.then(res => {
    console.log('success');
},err => {
    console.log(err);
    
})

// b.then(res => {
//     console.log(res);
//     return new Promise1((resolve, reject) => {
//         resolve('成功回调')
//     })

// })
//     .then(res => {
//         console.log(res);

//     }).catch(err => {
//         console.log(err);

//     })

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值