ICode9

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

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

2021-06-03 20:03:23  阅读:215  来源: 互联网

标签:resolve 封装 自定义 self 4Promise Promise reject catch onRejected


定义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);
                })
            }
        })
    }
}

标签:resolve,封装,自定义,self,4Promise,Promise,reject,catch,onRejected
来源: https://www.cnblogs.com/cianbei/p/14846606.html

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

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

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

ICode9版权所有