手写promise 对promise更详细的理解

首先还是上应用层的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

上一篇:102_《Delphi5编程实例与技巧》


下一篇:[力扣]24. 两两交换链表中的节点