手写promise-5 捕获错误及then链式调用其他状态代码补充

手写promise-5 捕获错误及then链式调用其他状态代码补充_第1张图片

前言
在上篇文章中介绍了,如何处理返回自身对象的处理,在本篇文章中将介绍如何捕获错误以及其他状态代码补充
代码演示
//设置promise 状态
const PENDING = "pending"; //等待状态
const FULFILLED = 'FULFILLED'; //成功状态
const REJECTED = 'rejected'; //失败状态

class MyPromise {
    constructor(executor) {
        //立即调用函数

        try {
            executor(this.resolve, this.reject)
        } catch (error) {
            this.reject(error)
        }
    }

    //初始化状态
    status = PENDING
        //初始化成功之后的值
    success = undefined
        //初始化失败之后的值
    error = undefined
        //用于保存成功回调,成功回调的默认值需要改成数组,因为只有数组可以存储多个回调函数
    successCallback = []
        //用于保存失败回调,失败回调的默认值需要改成数组,因为只有数组可以存储多个回调函数
    failCallback = []

    resolve = success => {
        //如果状态不是等待 则阻止程序执行
        if (this.status !== PENDING) return
            //把promise状态改为成功
        this.status = FULFILLED
            //保存成功之后的值
        this.success = success
            //如果有这个回调,那么要执行这个回调,并且把成功的值传递进去
            //this.successCallback && this.successCallback(this.success);
            //现在呢数组中存储了多个回调函数,所以遍历数组的每个函数并让其执行,上面的代码已经不符合要求
            //重新编写逻辑
            //这里使用while语句用successCallback.length作为循环条件,如果数组中有值,拿到数组中的第一个回调函数传值并执行
        while (this.successCallback.length) this.successCallback.shift()();
    }
    reject = error => {
        //如果状态不是等待 则阻止程序执行
        if (this.status !== PENDING) return
            //把promise状态改为失败
        this.status = REJECTED
            //保存失败之后的值
        this.error = error
            //如果有这个回调,那么要执行这个回调,并且把失败的原因传递进去   
            //this.failCallback && this.failCallback(this.error);
            //现在呢数组中存储了多个回调函数,所以遍历数组的每个函数并让其执行,上面的代码已经不符合要求
            //重新编写逻辑
            //这里使用while语句用failCallback.length作为循环条件,拿到数组中的第一个回调函数传值并执行
        while (this.failCallback.length) this.failCallback.shift()();

    }
    then(successCallback, failCallback) {
        //要实现then方法的链式调用必须创建一promise对象
        //新建一个promise对象
        let promise2 = new MyPromise((resolve, reject) => {
                //逻辑判断如果当前状态为成功 则执行成功的回调并且把保存成功的值传递进去
                if (this.status === FULFILLED) {

                    //此处仅仅将代码作为异步代码,延迟时间为0, 因为promise2 是在new MyPromise执行完成之后才能看到 在new MyPromise执行过程中是看不到的
                    //所以将代码变成异步代码
                    setTimeout(() => {
                        //捕获成功函数的错误信息
                        try {
                            //保存上一个函数的返回值
                            let x = successCallback(this.success)
                                //并且把返回值传递给下一个then方法
                                // resolve(x);

                            //判断X的值是普通值还是promise对象

                            //如果是普通值 直接调用resolve

                            //如果是promise对象 查看promise对象返回的结果

                            //再根据promise对象返回的结果 调用resolve还reject 

                            //所有同步代码执行完了才能看到promise2 
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (error) {
                            //手动调用reject方法 把错误信息传递给下一个promise函数
                            reject(error)
                        }


                    }, 0);


                    //逻辑判断如果当前状态为成功 则执行失败的回调并且把失败的原因传递进去
                } else if (this.status === REJECTED) {

                    setTimeout(() => {
                        //捕获错误函数的错误信息
                        try {
                            //保存上一个函数的返回值
                            let x = failCallback(this.error)
                                //并且把返回值传递给下一个then方法
                                // resolve(x);

                            //判断X的值是普通值还是promise对象

                            //如果是普通值 直接调用resolve

                            //如果是promise对象 查看promise对象返回的结果

                            //再根据promise对象返回的结果 调用resolve还reject 

                            //所有同步代码执行完了才能看到promise2 
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (error) {
                            //手动调用reject方法 把错误信息传递给下一个promise函数
                            reject(error)
                        }


                    }, 0);
                } else {
                    //当前状态为等待,也就是promise状态为pending,
                    //如果是等待的话那应该调用成功回调还是失败回调呢
                    //那当然是两个回调都无法调用,应为不知道到底是成功了还是还是失败了
                    //在这种情况下应该将成功回调和失败回调进行保存

                    //保存成功回调函数
                    //在这里有一个问题  this.successCallback一次只能存储一个函数这样的不符合要求
                    //所以在上面定义successCallback的时候将其定义为数组,这样就可以存储多个回调 ,将回调push进去

                    //重新编辑逻辑
                    this.successCallback.push(() => {
                        setTimeout(() => {
                            //捕获成功函数的错误信息
                            try {
                                //保存上一个函数的返回值
                                let x = successCallback(this.success)
                                    //并且把返回值传递给下一个then方法
                                    // resolve(x);

                                //判断X的值是普通值还是promise对象

                                //如果是普通值 直接调用resolve

                                //如果是promise对象 查看promise对象返回的结果

                                //再根据promise对象返回的结果 调用resolve还reject 

                                //所有同步代码执行完了才能看到promise2 
                                resolvePromise(promise2, x, resolve, reject)
                            } catch (error) {
                                //手动调用reject方法 把错误信息传递给下一个promise函数
                                reject(error)
                            }


                        }, 0);

                    });
                    //重新编辑逻辑
                    this.failCallback.push(() => {
                        setTimeout(() => {
                            //捕获错误函数的错误信息
                            try {
                                //保存上一个函数的返回值
                                let x = failCallback(this.error)
                                    //并且把返回值传递给下一个then方法
                                    // resolve(x);

                                //判断X的值是普通值还是promise对象

                                //如果是普通值 直接调用resolve

                                //如果是promise对象 查看promise对象返回的结果

                                //再根据promise对象返回的结果 调用resolve还reject 

                                //所有同步代码执行完了才能看到promise2 
                                resolvePromise(promise2, x, resolve, reject)
                            } catch (error) {
                                //手动调用reject方法 把错误信息传递给下一个promise函数
                                reject(error)
                            }


                        }, 0);
                    });
                }
            })
            //返回promise对象
        return promise2
    }
}
//定义函数用于判断返回的是普通值还是promise对象
function resolvePromise(promise2, x, resolve, reject) {
    //逻辑判断是返回的是当前的promise对象 如果是抛出错误并且阻止程序执行
    if (promise2 === x) {

        return reject(new TypeError('Chaining cycle detected for promise #'))

    }
    //逻辑判断如果是promise对象
    if (x instanceof MyPromise) {
        //如果是成功的回调 就把值传递进去 失败的话就把失败的原因传递进去
        //  x.then(success => resolve(success), error => reject(error))
        //下面是简写写法
        x.then(resolve, reject)
    } else {
        //逻辑判断是普通值直接传递进去
        resolve(x)
    }

}
//遵循commjs规范 导出
module.exports = MyPromise;
示范
let MyPromise = require('./手写promise-5 捕获错误及 then 链式调用其他状态代码补充');

let promise = new MyPromise((resolve, reject) => {

    setTimeout(() => {

        resolve('success')

    }, 200);

})
promise
    .then(res => {
        console.log(res);
        return 'aaa'
    }, err => {
        console.log(err);
        return '11111'
    })
    .then(res => {
        console.log(res);
        return 10000
    }, error => {
        //console.log(error)
        console.log(error)
    })
//打印结果
//aaa
//11111

谢谢观看,如有不足,敬请指教

你可能感兴趣的:(手写Promise,前端,javascript,node.js,es6)