《Promise学习笔记》- 4Promise自定义封装之thencatch的封装

Posted 仙贝wang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Promise学习笔记》- 4Promise自定义封装之thencatch的封装相关的知识,希望对你有一定的参考价值。

定义then方法

前面只是对then方法简单的定义,另外还需要注意then方法的两大特性:

  • 同时指定多个回调都会被调用;

    实现方法:在实例对象自身身上初始化一个空数组callbacks,当状态为pending时,将多个回调以一组对象的形式push进数组中用于被执行。

  • then方法的链式调用,因为then方法能够返回一个promise对象。

// 定义then方法
then(onResolved,onRejected){
    // 保存this指向
    const self = this;
    // then返回结果仍然是一个Promise
    return new Promise((resolve,reject)=>{
        // 封装回调函数(是代码简洁)
        function callback(type){
            try {
                let res = type(self.PromiseResult);
                if(res instanceof Promise){
                    res.then(v => {
                        resolve(v);
                    },r => {
                        reject(r);
                    })
                }else{
                    resolve(res);
                }
            } catch (e) {
                reject(e)
            }
        }
        // 状态为成功时的回调
        if(this.PromiseState === \'fulfilled\'){
            callback(onResolved);
        };
        // 状态为失败时的回调
        if(this.PromiseState === \'rejected\'){
            callback(onRejected);
        }
        // 状态为pending时,将多个回调压入到callbacks数组中
        if(this.PromiseState === \'pending\'){
            this.callbacks.push({
                onResolved:function(){
                    callback(onResolved);
                },
                onRejected:function(){
                    callback(onRejected);
                }
            })
        }
    })
}

定义catch方法

定义好then方法之后,catch方法的定义就会简单很多!我们知道,可以将catch方法看作是then(undefined,onRejected)的语法糖,所以在定义时可以直接调用实例身上的then方法!

// 定义catch方法
catch(onRejected){
    return this.then(undefined,onRejected)
}

自定义封装终极版

综合了一下前面的定义,下面是完整的自定义代码!主要实现了构造器函数和Promise.resolve()、Promise.reject()、Promise.all()、Promise.race()、Promise.prototype.then()、Promise.prototype.catch()这六个方法!大家可以试着敲敲看,如有错误还请指正,谢谢!

class Promise{
    // 定义构造器函数
    constructor(executor){
        // 初始化状态和状态值
        this.PromiseState = \'pending\';
        this.PromiseResult = null;
        // 保存this,由于函数内部this默认指向window
        const self = this;
        // 定义一个空数组,用于保存回调
        this.callbacks = [];
        // 定义resolve函数
        function resolve(data){
            // 保证状态只能修改一次
            if(self.PromiseState !== \'pending\') return;
            // 状态变为成功
            self.PromiseState = \'fulfilled\';
            // 状态值变为传入的参数值
            self.PromiseResult = data;
            // 异步任务时成功的回调,保证多个then的同时调用
            self.callbacks.forEach(item => {
                item.onResolved(data);
            });
        };
        // 定义reject函数
        function reject(data){
            if(self.PromiseState !== \'pending\') return;
            self.PromiseState = \'rejected\';
            self.PromiseResult = data;
            // 异步任务时失败的回调
            self.callbacks.forEach(item => {
                item.onRejected(data);
            });
        };
        // 当抛出异常时,使用try...catch捕获
        try{
            executor(resolve,reject);
        }catch(e){
            // 直接调用reject函数将对象状态变为失败,此时e为失败的状态值
            reject(e);
        }
    }
    // 定义then方法
    then(onResolved,onRejected){
        // 保存this指向
        const self = this;
        // then返回结果仍然是一个Promise
        return new Promise((resolve,reject)=>{
            // 封装回调函数
            function callback(type){
                try {
                    let res = type(self.PromiseResult);
                    if(res instanceof Promise){
                        res.then(v => {
                            resolve(v);
                        },r => {
                            reject(r);
                        })
                    }else{
                        resolve(res);
                    }
                } catch (e) {
                    reject(e)
                }
            }
            // 状态为成功时的回调
            if(this.PromiseState === \'fulfilled\'){
                callback(onResolved);
            };
            // 状态为失败时的回调
            if(this.PromiseState === \'rejected\'){
                callback(onRejected);
            }
            // 状态为pending时,将多个回调压入到callbacks数组中
            if(this.PromiseState === \'pending\'){
                this.callbacks.push({
                    onResolved:function(){
                        callback(onResolved);
                    },
                    onRejected:function(){
                        callback(onRejected);
                    }
                })
            }
        })
    }
    // 定义catch方法
    catch(onRejected){
        return this.then(undefined,onRejected)
    }
    // 定义resolve方法
    static resolve(value){
        return new Promise((resolve,reject)=>{
            if(value instanceof Promise){
                value.then(v => {
                    resolve(v);
                },r => {
                    reject(r);
                })
            }else{
                resolve(value);
            }
        })
    }
    // 定义reject方法
    static reject(reason){
        return new Promise((resolve,reject)=>{
            reject(reason)
        })
    }
    // 定义all()方法
    static all(promises){
        return new Promise((resolve,reject)=>{
            // 记录数组中成功状态Promise的个数
            let count = 0;
            // 保存成功的状态值
            let arr = [];
            for(let i=0;i<promises.length;i++){
                promises[i].then(v => {
                    count++;
                    arr[i]=v;
                    // 如果成功的个数等于数组长度,则说明每个都成功
                    if(count === promises.length){
                        resolve(arr);
                    }
                },r => {
                    reject(r);
                })
            };
        })
    }
    // 定义race()方法
    static race(promises){
        return new Promise((resolve,reject)=>{
            for(let i=0;i<promises.length;i++){
                promises[i].then(v => {
                    resolve(v);
                },r => {
                    reject(r);
                })
            }
        })
    }
}

以上是关于《Promise学习笔记》- 4Promise自定义封装之thencatch的封装的主要内容,如果未能解决你的问题,请参考以下文章

Promise原理讲解 async+await应用(异步回调解决方案)

ui-router

Promise学习笔记

Promise学习笔记

《Promise学习笔记》- 2Promise相关常用方法总结

Promise/commonJS/AMD学习笔记