实现一个完整的promise

本文从Promise的基本概念出发,详细介绍了如何使用Promise解决异步回调问题,并通过实例逐步讲解了Promise的内部实现机制,包括状态管理、回调处理及链式调用的实现。

promise 是什么

Promise 是为了解决异步回调问题,处理异步回调使得代码层次更加清晰,便于理解,更加容易维护
复制代码

首先我们简单实用一个一下es6的promise 然后去简单实现一下,用setTimeout 简单的模拟异步

    function fn1(resolve,reject){
        setTimeout(()=>{
            console.log(1)
            resolve(1);
        })
    }

    

    new Promise(fn1).then((data)=>{
        console.log('data:'+data); // data : 1
        
    })

        // 结果是先打出一个1 然后在打出 data: 1
复制代码

简单的实现上边代码的promise

- 首先Promise 是一个函数 有两个参数 resolve 和 reject 一个成功的参数一个失败的参数
- promise 有三个状态  pending 等待态 fulfilled 成功态 rejected 失败态
- 如果 函数没有返回成功或者失败 那么 他一直就是等待态, 需要两个数组把函数存起来,等待他的状态变化 再去执行相对的函数 设置两个数组 一个为 成功的数组 onResolvedCallbacks 一个为失败的数组 onRejectedCallbacks
- promise 一旦成功 就不能 失败  一旦失败就不能成功 不能进行转换 所以执行成功或者失败的函数时 要判断是不是 等待态 如果是等待态 在去执行 成功或失败的函数 并且把其变成响应的状态,把其值 改变,并且执行回调函数
复制代码
 class Promise{
     constructor(exectour){
         this.status="pending" //定义状态
         this.onResolvedCallbacks=[]; // 成功函数的数组
         this.onRejectedCallbacks=[];   // 失败函数的数组
         this.value=undefined; //成功的返回值
         this.season=undefined; //失败的返回值
         let resolve=(value)=>{ // 成功的回调函数
            if(this.status==='pending'){
                this.status='fulfilled';
                this.value=value;
                this.onResolvedCallbacks.forEach(fn=>fn(this.value))
            } 
         }
         let reject=(reason)=>{ 失败的回调函数
           if(this.status==='pending'){
                this.status='rejected';
                this.reason=reason;
                this.onRejectedCallbacks.forEach(fn=>fn(this.reason))
            }    
         }
        exectour(resolve,reject);
     }
 }
 module.exports=Promise;

复制代码

上边代码的then 方法

- then 的参数有两个,第一个参数是成功的参数 onFulfilled,第二个参数是失败的参数 onRejected
- 执行到then 的时候 有三个状态  成功 失败 和等待  成功的时候执行成功的函数 失败的时候执行失败的函数,等待的时候就存到他们各自函数的数组里边
复制代码
class Promise{
    constructor(exectour){
        //code
    }
    then(onFulfilled,onRejected){
        
        if(this.status==='fulfilled'){//成功态
            onFulfilled(this.value)
            
        }
        
        if(this.status==='rejected'){//失败态
            this.onRejected(this.reason)
        }
        
        if(this.status==='pending'){//等待态
            this.onResolvedCallbacks.push(onFulfilled);  
            this.onRejectedCallbacks.push(onRejected);
        }
    }
    
}
module.exports=Promise;
复制代码

完整代码


class Promise{
    constructor(exectour){
         this.status="pending" //定义状态
         this.onResolvedCallbacks=[]; // 成功函数的数组
         this.onRejectedCallbacks=[];   // 失败函数的数组
         this.value=undefined; //成功的返回值
         this.season=undefined; //失败的返回值
         let resolve=(value)=>{ // 成功的回调函数
            if(this.status==='pending'){
                this.status='fulfilled';
                this.value=value;
                this.onResolvedCallbacks.forEach(fn=>fn(this.value))
            } 
         }
         let reject=(reason)=>{ 失败的回调函数
           if(this.status==='pending'){
                this.status='rejected';
                this.reason=reason;
                this.onRejectedCallbacks.forEach(fn=>fn(this.reason))
            }    
         }
        exectour(resolve,reject);
     }
     then (onFulfilled,onRejected){
        
        if(this.status==='fulfilled'){//成功态
            onFulfilled(this.value)
            
        }
        
        if(this.status==='fulfilled'){//失败态
            this.onRejected(this.reason)
        }
        
        if(this.status==='pending'){//等待态
            this.onResolvedCallbacks.push(onFulfilled);  
            this.onRejectedCallbacks.push(onRejected);
        }
    }
 }

module.exports=Promise;
复制代码

使用 自己写的promise


 const Promise= require('./Promise');

 function fn1(resolve,reject){
        setTimeout(()=>{
            console.log(1)
            resolve(1);
        })
    }

    

    new Promise(fn1).then((data)=>{
        console.log('data:'+data); // data : 1
        
    },reason=>{
		console.log('raeson'+reson)
	})

复制代码
总结 这就简单实现了一个漏洞百出的promise ,后边将继续完善我们promise ,上边的promise如果回调的时候 抛出一个异常那么我们现在实现的promise 是不会做出反应的所以要考虑一下这种情况
class Promise{
    constructor(exectour){
        //code
        
        try{
             exectour(resolve,reject);
        }catch(e){
            reject(e);
        }
    }
    
}


复制代码
我们目前完成的promise 是不能链式的 所以下一步就是实现链式,要想实现链式 那么 回调函数返回的就是一个promise 才会现实链式
根据 promise a+的规范 返回一个名字叫 promise2 的一个promise
x 是回调函数的返回值,要看看 是不是promise 如果是 取他的结果,作为promise2 成功的结果
如果返回的是一个普通值, 作为promise2 成功的结果

然后我们用 resilvePromise 解析 x 和promise2 之间的关系
复制代码
class Promise{
    constructor(exectour){
        //code
        
       
    }
    then(onFulfilled,onRejected){
        let promise2
        if(this.status==='fulfilled'){//成功态
            promise2=new Promise((resolve,reject)=>{
                let x= onFulfilled(this.value);
                resolvePromise(promise2,x,resolve,reject)
            })
            
            
        }
        
        if(this.status==='fulfilled'){//失败态
            
            promise2=new Promise((resolve,reject)=>{
                let x= this.onRejected(this.reason)
                resolvePromise(promise2,x,resolve,reject)
            })
        }
        
        if(this.status==='pending'){//等待态
            promise2=new Promise((resolve,reject)=>{
                this.onResolvedCallbacks.push(()=>{
                    let x=onFulfilled(this.value)
                    resolvePromise(promise2,x,resolve,reject)
                    
                });  
                this.onRejectedCallbacks.push(()=>{
                    let x= this.onRejected(this.reason)
                    resolvePromise(promise2,x,resolve,reject)
                });
            })
            
            
        }
        return promise2 // 调用then后返回一个新的promise
        
    }
    
}
复制代码
那么我们接下来实现 resolvePromise解析 x 和promise2 之间的关系
function resolvePromise(promise2,x,resolve,reject){
   // 首先判断promise2 和x 是不是同一个promise 如果是报错
   if(promise2===x){
       reject(new TypeError('循环引用'))
   }
   
   //如果x不是null 并且 是对象或者函数 我们进进一步去做处理 否则我们 认为他是一个值 直接传成功就可以了
   if(x!==null && (typeof x === 'object' || typeof x ==='function')){
       // 
       let called //防止成功或失败再去调用
       
       try{  //防止取的then 出现异常
            let then=x.then
            
            if(typeof then=='function'){//如果then 是一个函数我们就认为他是一个promise
            then.call(x,y=>{ // call 第一个参数是this ,后面的是成功的回调和失败的回调
                //y 是promise就继续递归解析
                if(called) return false;
                called= true;
                resolvePromise(promise2,y,resolve,reject);
            },r=>{
                if(called) return false;
                called= true;
                reject(r)
                
            })
                
            }else{
                resolve(x) //then shi 一个普通对象 就直接成功   
            }
           
       }catch(e){
           if (called) return;
          called = true;
          reject(e);
       }
       
       
   }else{
       resolve(x);
   }
}


复制代码
那么 我们基本上就完成了一个promise 不过promise 的几个方法还没有实现 那么我们继续完成promise上的另几个方法
class Promise {
    //code
    catch(onRejected) {
     // catch就是then的没有成功的简写
     return this.then(null, onRejected);
   }
}
Promise.resolve = function (val) {
 return new Promise((resolve, reject) => resolve(val))
}
Promise.reject = function (val) {
return new Promise((resolve, reject) => reject(val));
}
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
 for (let i = 0; i < promises.length; i++) {
   promises[i].then(resolve, reject);
 }
});
}
Promise.all = function (promises) {
return new Promise((resolve,reject)=>{
 let arr = [];
 let i = 0; // i的目的是为了保证获取全部成功,来设置的索引
 function processData(index,data) {
   arr[index] = data;
   i++;
   if (i === promises.length){
     resolve(arr);
   }
 }
 for(let i = 0;i<promises.length;i++){
   promises[i].then(data=>{
     processData(i,data);
   }, reject);
 }
})
}
Promise.deferred = Promise.defer = function () {
let dfd = {};
dfd.promise = new Promise((resolve, reject) => {
 dfd.resolve = resolve;
 dfd.reject = reject;
})
return dfd;
}
复制代码

这就基本完成了一个promise 代码和语言的归纳还比较稚嫩,希望大家多多指点。

转载于:https://juejin.im/post/5b21d087f265da6e01175760

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值