ICode9

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

手写promise 对promise更详细的理解

2022-02-05 15:31:50  阅读:210  来源: 互联网

标签:function status resolve self reason promise 详细 reject 手写


首先还是上应用层的promise代码

以便对结构的理解

let remember = true;
        let getMoney = new Promise((resolve,reject)=>{
            if(remember){
                let money = 999
                resolve(money)
            }else{
                let noMoney = new Error('今年你已经毕业了,没有红包了');
                reject(noMoney)
            }
        })

        let test = function(){
            getMoney.then((fulfilled)=>{
                console.log(fulfilled);
            }).catch((rejected)=>{
                console.log(rejected.message);
            })
        }

        test()

基本结构

这里我们可以看出 一个promise实例

我们需要 知道他的状态 一开始为panding 待处理状态

如果成功 返回一个值

如果失败 返回错误原因

由应用层代码来看

需要一个处理成功的方法resolve 和 处理失败的方法reject

还有一个.then的方法(.catch方法实质上就是.then方法的另一种写法 搭架子时候暂时忽略)

我们每构造一个新promise实例  都要用到then方法  那么我们把then写在我们自己构造的promise原型中  构造函数可以继承使用

理清逻辑  架子为

function myPromise(){
            let self = this; //接收当前内容
            self.status = 'pending'; //状态
            self.value = null; //成功之后,返回的数据
            self.reason = null; //失败了,失败的原因

            //返回成功的结果
            function resolve(){

            }

            //返回失败的原因
            function reject(){

            }


        }
        //2.then()
        myPromise.prototype.then = function(){

        }

        //3.初级调用
        let demo = new myPromise((resolve,reject)=>{
            console.log("111");
        })

当然到了这里  这个111是打印不出来的  显而易见  没有调用

function myPromise(excutor){
            let selt = this; //接收当前内容
            self.status = 'pending'; //状态
            self.value = null; //成功之后,返回的数据
            self.reason = null; //失败了,失败的原因

            //返回成功的结果
            function resolve(){

            }

            //返回失败的原因
            function reject(){

            }
            try {
                excutor(resolve,reject)
            } catch (error) {
                reject(error)
            }

        }

所以我们补全代码  传入一个执行器excutor  执行器方法也是调用resolve reject

当我们运用new Promise时候传两个参数  resolve reject  这效果是一样的  同步立即执行

之后进行进一步的完善

function resolve(value){
                //5.1
                if(self.status === 'pending'){
                    self.value = value //保存成功的结果
                    self.status = 'fulfilled' //状态更改
                }
            }

            //返回失败的原因
            function reject(reason){
                //5.2
                if(self.status === 'pending'){
                    self.reason = reason //失败原因
                    self.status = 'rejected' //状态更改
                }
            }

初始状态肯定为pending待处理  然后开始完善resolve 和 reject方法

成功即保存结果  失败即抛出原因

当然此时的状态也要随之改变为fulfilled或者rejected

无论成功与否  下面就要进入到then方法里

//6.确保传进来的是方法 如果不是的话  定义一个方法
            myFulfilled = typeof myFulfilled === 'function' ? 
            myFulfilled : function(data) { resolve(data) }
            myRejceted = typeof myRejected === 'function' ? 
            myRejected : function(err) { throw err }

then方法写完  就要开始实现如何实现异步操作   Promise是一个比较好的异步操作方法  当然异步也要考虑进去

//7.暂存区
            self.fulfilledBack = [];
            self.rejectBack = [];

先定义一个暂存区  这个暂存也是在then方法里存

因为由应用层代码可以看出   promise实例进行.then方法之后 才可执行相应操作

let self = this;
            
            if(self.status === 'pending'){
                self.fulfilledBack.push(myFulfilled);
                self.rejectedBack.push(myReject);

            }

暂存之后的数据 要取出  当成功时候 在resolve取出  失败时候 在reject取出

function resolve(value){
                //5.1
                if(self.status === 'pending'){
                    self.value = value //保存成功的结果
                    self.status = 'fulfilled' //状态更改

                    //9.状态发生改变 => 依次取出
                    self.fulfilledBack.forEach(item => item(value))
                }
            }

            //返回失败的原因
            function reject(reason){
                //5.2
                if(self.status === 'pending'){
                    self.reason = reason //失败原因
                    self.status = 'rejected' //状态更改
                    self.rejectedBack.forEach(item => item(reason))

                }
            }

这样继续完善resolve方法  和  reject 方法

到这里就算是结束了

如果有需要  我把整个代码放过来 自提

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>手写promise</title>
</head>
<body>
    <h2>手写promise</h2>
    <script>
        function myPromise(excutor){
            let self = this; //接收当前内容
            self.status = 'pending'; //状态
            self.value = null; //成功之后,返回的数据
            self.reason = null; //失败了,失败的原因
            //7.暂存区
            self.fulfilledBack = [];
            self.rejectedBack = [];

            //返回成功的结果
            function resolve(value){
                //5.1
                if(self.status === 'pending'){
                    self.value = value //保存成功的结果
                    self.status = 'fulfilled' //状态更改

                    //9.状态发生改变 => 依次取出
                    self.fulfilledBack.forEach(item => item(value))
                }
            }

            //返回失败的原因
            function reject(reason){
                //5.2
                if(self.status === 'pending'){
                    self.reason = reason //失败原因
                    self.status = 'rejected' //状态更改
                    self.rejectedBack.forEach(item => item(reason))

                }
            }
            //4.excutor =>立即执行
            try {
                excutor(resolve,reject)
            } catch (err) {
                reject(err)
            }

        }
        //2.then()
        myPromise.prototype.then = function(myFulfilled,myRejected){
            //6.确保传进来的是方法 如果不是的话  定义一个方法
            myFulfilled = typeof myFulfilled === 'function' ? 
            myFulfilled : function(data) { resolve(data) }
            myRejected = typeof myRejected === 'function' ? 
            myRejected : function(err) { throw err }

            let self = this;
            
            //8.暂存回调函数
            if(self.status === 'pending'){
                self.fulfilledBack.push(myFulfilled);
                self.rejectedBack.push(myRejected);

            }
        }

        //3.初级调用
        let demo = new myPromise((resolve,reject)=>{
            console.log("111")
            setTimeout(() => {
                resolve(222)
            }, 2000);
        })
        //console.log(demo);
        let test = function() {
            demo.then((data)=>{
                console.log(data)
                })
        }
        test()
        

        
        
    </script>
</body>
</html>

如果对手写的原理层代码感觉有问题  可以对照这个应用层代码   代码在文章最开始有  这是对应用层代码的解释

https://blog.csdn.net/qq_45158336/article/details/122782823

标签:function,status,resolve,self,reason,promise,详细,reject,手写
来源: https://blog.csdn.net/qq_45158336/article/details/122783169

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

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

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

ICode9版权所有