带大家如何实现一个手写 Promise

声明 Promise

首先,promise 是一个类,所以用class来声明。
1. new Promise((resolve, reject)=>{}), 因此要传入一个参数(函数),叫做executor;
2. executor 里面有两个参数,resolve 和 rejecte ,表示成功/失败;


class Promise{
   
    // 构造器
    constructor(executor){
   
        // 成功
        let resolve = () => {
   };
        // 失败
        let reject = () => {
   };
        // 立即执行
        executor(resolve,reject)
    }
}

解决基本状态

官方对Promise有如下规定:
1. Promise 存在三个状态(state):pending、fulfilled、rejected;
2. pending(等待态)为初始态,并可以转化为 fulfilled(成功态)和rejected(失败态);
3. 成功时,不可转为其他状态,并且需要有一个不可改变的值(value) ;
4. 失败时,不可转为其他状态,并且需要有一个不可改变的原因(reason) ;
5. new Promise((resolve, reject)=>{resolve(value)}) resolve为成功,接收value参数,并且改变状态为fulfilled,不可以再次改变;
6. new Promise((resolve, reject)=>{reject(reason)}) reject为成功,接收reason参数,并且改变状态为rejected,不可以再次改变;
7. 若 executor 函数报错,直接执行reject();


class Promise {
   
    constructor(executor) {
   
        // 初始化state为等待态
        this.state = 'pending';
        //成功的值
        this.value = undefined;
        //失败的原因
        this.reason = undefined;
 
        let resolve = value => {
   
            // state 改变,resolve 调用就会失败
            if (this.state === 'pending') {
   
                // resolve调用后,state转化为成功态
                this.state = 'fulfilled';
                // 储存成功的值
                this.value = value;
            }
        }
        let reject = reason => {
   
            // state 改变,reject 调用就会失败
            if (this.state === 'pending') {
   
                // resolve调用后,state转化为成功态
                this.state = 'rejected';
                // 储存成功的值
                this.reason = reason;
            }
        }
 
        // 若 executor 执行报错,则直接调用 reject
        try{
   
            executor(resolve,reject);
        }catch(err){
   
            reject(err);
        }
 
    }
}

then方法

promise 有一个叫做 then 的方法,里面有两个参数:onFulfilled,onRejected,成功返回值,失败返回原因。

1. 当state状态为fulfilled,则执行onFulfilled,传入this.value;

2. 当state状态为rejected,则执行onRejected,传入this.reason;

3. 因此把onFulfilled、onRejected看作函数,则必须分别在fulfilled,rejected之后被调用,value或reason依次作为他们的第一个参数 ;

class Promse {
   
    constructor(executor) {
   ... }
    // then方法,有两个参数 onFulfilled 和 onRejected
    then(onFulfilled, onRejected) {
   
        // 状态为fulfilled,执行onFulfilled,传入成功的值
        if (this.state === 'fulfilled') {
   
            onFulfilled(this.value)
        }
        // 状态为rejected,执行onRejected,传入失败的原因
        if (this.state === 'rejected') {
   
            onRejected(this.reason)
        }
    }
}

功能已经基本实现,但无法针对setTimeout

解决异步实现

现在可以基本实现简单的同步代码,但是当resolve在setTimeout内执行,then这时的state还是pending的状态,所以我们需要在then调用的时候,将失败和成功存到各自的数组,一旦reject或者resolve,就调用他们

类似订阅发布,先将then里面的两个函数储存起来,由于一个promise可以有多个then,所以存在同一个数组内


 // 解决异步调用
class Promise {
   
    constructor(executor){
   
        this.state = 'pending';
        this.value = undefined;
        this.reason = undefined;
        // 成功存放的数组
        this.onResolvedCallbacks = [];
        // 失败存放的数组
        this.onRejectedCallbacks = [];
 
        let resolve = value =>{
   
            if(this.state === 'pending'){
   
                this.state = 'fulfilled'
                this.value = value
                // 一旦resolve执行,调用成功数组的函数
                this.onResolvedCallbacks.forEach(fn => fn())
            }
        }
        let reject = reson => {
   
            if(this.state === 'padding'){
   
                this.state = 'fulfilled'
                this.reason = reson 
                // 一旦reject执行,调用失败数组的函数
                this.onRejectedCallbacks.forEach(fn => fn())
            }
        }
 
        then(onFulfilled,onRejected){
   
            if(this.state === 'fulfilled'){
   
                onFulfilled(this.value)
            };
            if(this.state === 'rejected'){
   
                onRejected(this.reason)
            }
            // 当状态state为pending时
            if(this.state === 'pending'){
   
                // onFulfilled 传入到成功数组
                this.onResolvedCallbacks.push(() 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值