从简到难手把手教你写Promise源码 手写 Promise源码

先写个简易版的

const PENDING = 'pengding'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor(excecutor){
        excecutor(this.resolve,this.rejected)
    }
    status = PENDING
     // 成功之后的值
    value = undefined;
    // 失败后的原因
    reason = undefined;
    resolve = value =>{
        // statu改变了就不能再改变了 所以先判断一下
        if(this.status !== PENDING) return
       this.status = FULFILLED 
       this.value = value
    }
    rejected = value =>{
        if(this.status !== PENDING) return
        this.status = REJECTED 
        this.value = value
    }
    then = (successCallBack,failCallBack) =>{
        if(this.status === FULFILLED){
            successCallBack(this.value)
        }else if(this.status === REJECTED){
            failCallBack(this.reason)
        }else{
            
        }
    }
}

module.exports = MyPromise

导入执行

const Mypromise = require('./myPromise')



const my = new Mypromise((res,rej)=>{
    res(1)
    rej(2)
})
console.log(my);
my.then(v => console.log(v),v => console.log(v))

简易版加入异步逻辑

在这里插入图片描述
如果直接then会什么都不执行 进入else的分支
上代码

const PENDING = 'pengding'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor(excecutor){
        excecutor(this.resolve,this.rejected)
    }
    status = PENDING
     // 成功之后的值
    value = undefined;
    // 失败后的原因
    reason = undefined;
    successCallBack = undefined
    failCallBack = undefined
    resolve = value =>{
        // statu改变了就不能再改变了 所以先判断一下
        if(this.status !== PENDING) return
       this.status = FULFILLED 
       this.value = value
    //    如果有就调用
       this.successCallBack &&  this.successCallBack(this.value)
    }
    rejected = value =>{
        if(this.status !== PENDING) return
        this.status = REJECTED 
        this.reason = value
        this.failCallBack &&  this.failCallBack(this.reason)
    }
    then (successCallBack,failCallBack) {
        if(this.status === FULFILLED){
            successCallBack(this.value)
        }else if(this.status === REJECTED){
            failCallBack(this.reason)
        }else{
            // 如果status没改变说明 res和rej都没执行 先存起来
            this.successCallBack = successCallBack  
            this.failCallBack = failCallBack 
        }
    }
}

module.exports = MyPromise

在这里插入图片描述

简易版加入异步逻辑实现多次调用添加处理函数

const PENDING = 'pengding'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor(excecutor){
        excecutor(this.resolve,this.rejected)
    }
    status = PENDING
     // 成功之后的值
    value = undefined;
    // 失败后的原因
    reason = undefined;
    successCallBack = []
    failCallBack = []
    resolve = value =>{
        // statu改变了就不能再改变了 所以先判断一下
        if(this.status !== PENDING) return
       this.status = FULFILLED 
       this.value = value
    //    如果有就调用
    while(this.successCallBack.length) this.successCallBack.shift()(this.value)
    }
    
    rejected = value =>{
        if(this.status !== PENDING) return
        this.status = REJECTED 
        this.reason = value
        while(this.failCallBack.length) this.failCallBack.shift()(this.reason)
    }
    
    then (successCallBack,failCallBack) {
        if(this.status === FULFILLED){
            successCallBack(this.value)
        }else if(this.status === REJECTED){
            failCallBack(this.reason)
        }else{
            // 如果status没改变说明 res和rej都没执行 先存起来
            this.successCallBack.push(successCallBack)   
            this.failCallBack.push(failCallBack)   
        }
    }
}

module.exports = MyPromise

在这里插入图片描述

实现then的链式调用 part1

const PENDING = 'pengding'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor(excecutor){
        excecutor(this.resolve,this.rejected)
    }
    status = PENDING
     // 成功之后的值
    value = undefined;
    // 失败后的原因
    reason = undefined;
    successCallBack = []
    failCallBack = []
    resolve = value =>{
        // statu改变了就不能再改变了 所以先判断一下
        if(this.status !== PENDING) return
       this.status = FULFILLED 
       this.value = value
    //    如果有就调用
    while(this.successCallBack.length) this.successCallBack.shift()(this.value)
    }
    
    rejected = value =>{
        if(this.status !== PENDING) return
        this.status = REJECTED 
        this.reason = value
        while(this.failCallBack.length) this.failCallBack.shift()(this.reason)
    }
    // 实现链式调用then
    
    then (successCallBack,failCallBack) {
        let promise2 = new MyPromise((res,rej)=>{
           
            if(this.status === FULFILLED){
                let x =   successCallBack(this.value)
                res(x)
              }else if(this.status === REJECTED){
                  failCallBack(this.reason)
              }else{
                  // 如果status没改变说明 res和rej都没执行 先存起来
                  this.successCallBack.push(successCallBack)   
                  this.failCallBack.push(failCallBack)   
              }
        });
        

        return promise2
    }
}

module.exports = MyPromise

结果

const my = new Mypromise((res,rej)=>{
    res(1)
    // setTimeout(()=>{
    //     res(1)
    // },1500)
    // rej(2)
})

my.then(v => 100,v => console.log(v))
.then(v => console.log(v),v => console.log(v)) 100

实现then的链式调用 part2

判断返回值是普通值还是promise对象

const PENDING = 'pengding'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor(excecutor){
        excecutor(this.resolve,this.rejected)
    }
    status = PENDING
     // 成功之后的值
    value = undefined;
    // 失败后的原因
    reason = undefined;
    successCallBack = []
    failCallBack = []
    resolve = value =>{
        // statu改变了就不能再改变了 所以先判断一下
        if(this.status !== PENDING) return
       this.status = FULFILLED 
       this.value = value
    //    如果有就调用
    while(this.successCallBack.length) this.successCallBack.shift()(this.value)
    }
    
    rejected = value =>{
        if(this.status !== PENDING) return
        this.status = REJECTED 
        this.reason = value
        while(this.failCallBack.length) this.failCallBack.shift()(this.reason)
    }
    // 实现链式调用then
    
    then (successCallBack,failCallBack) {
        let promise2 = new MyPromise((res,rej)=>{
           
            if(this.status === FULFILLED){
                let x =   successCallBack(this.value)
                resolvePromise(x,res,rej)
                // res(x)
            // 判断 x 的值是普通值还是promise对象
            // 如果是普通值 直接调用resolve 
            // 如果是promise对象 查看promsie对象返回的结果 
            // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
              }else if(this.status === REJECTED){
                  failCallBack(this.reason)
              }else{
                  // 如果status没改变说明 res和rej都没执行 先存起来
                  this.successCallBack.push(successCallBack)   
                  this.failCallBack.push(failCallBack)   
              }
        });
        

        return promise2
    }
}
function resolvePromise(x,res,rej){
    if(x instanceof MyPromise){
        x.then(res,rej)
     
    }else{
        res(x)
    }
}

module.exports = MyPromise

结果

// const MyPromise = require('../myPromise')
const Mypromise = require('./myPromise')
// 


const my = new Mypromise((res,rej)=>{
    res(1)
    // setTimeout(()=>{
    //     res(1)
    // },1500)
    // rej(2)
})

function other (){
    return new Mypromise((res,rej)=>{
        res('other')
    })
}

my.then(v => other(),v => console.log(v))
.then(v => console.log(v),v => console.log(v)) 
2
other

then 方法链式调用识别 Promise 对象自返回

防止调自己
在这里插入图片描述

const PENDING = 'pengding'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor(excecutor){
        excecutor(this.resolve,this.rejected)
    }
    status = PENDING
     // 成功之后的值
    value = undefined;
    // 失败后的原因
    reason = undefined;
    successCallBack = []
    failCallBack = []
    resolve = value =>{
        // statu改变了就不能再改变了 所以先判断一下
        if(this.status !== PENDING) return
       this.status = FULFILLED 
       this.value = value
    //    如果有就调用
    while(this.successCallBack.length) this.successCallBack.shift()(this.value)
    }
    
    rejected = value =>{
        if(this.status !== PENDING) return
        this.status = REJECTED 
        this.reason = value
        while(this.failCallBack.length) this.failCallBack.shift()(this.reason)
    }
    // 实现链式调用then
    
    then (successCallBack,failCallBack) {
        let promise2 = new MyPromise((res,rej)=>{
           
            if(this.status === FULFILLED){
               setTimeout(()=>{
                let x =   successCallBack(this.value)
                //new 的过程中拿不到promise2 改成异步的就行了
                resolvePromise(promise2,x,res,rej)
                // res(x)
            // 判断 x 的值是普通值还是promise对象
            // 如果是普通值 直接调用resolve 
            // 如果是promise对象 查看promsie对象返回的结果 
            // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
               },0)
              }else if(this.status === REJECTED){
                  failCallBack(this.reason)
              }else{
                  // 如果status没改变说明 res和rej都没执行 先存起来
                  this.successCallBack.push(successCallBack)   
                  this.failCallBack.push(failCallBack)   
              }
        });
        

        return promise2
    }
}
function resolvePromise(promise2,x,res,rej){
    if(promise2 === x){
        return rej(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    if(x instanceof MyPromise){
        x.then(res,rej)
     
    }else{
        res(x)
    }
}

module.exports = MyPromise

结果

let p1 = my.then(v => 
    {return p1},v => console.log(v))

    p1.then(v => console.log(v),v => console.log(v))
    
// TypeError: Chaining cycle detected for promise #<Promise>

捕获错误及 then 链式调用其他状态代码补充

const PENDING = 'pengding'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor(excecutor){
        try {
            excecutor(this.resolve,this.rejected)
        } catch (e) {
            this.rejected(e);
        }
    }
    status = PENDING
     // 成功之后的值
    value = undefined;
    // 失败后的原因
    reason = undefined;
    successCallBack = []
    failCallBack = []
    resolve = value =>{
        // statu改变了就不能再改变了 所以先判断一下
        if(this.status !== PENDING) return
       this.status = FULFILLED 
       this.value = value
    //    如果有就调用
    while(this.successCallBack.length) this.successCallBack.shift()()
    }
    
    rejected = value =>{
        if(this.status !== PENDING) return
        this.status = REJECTED 
        this.reason = value
        while(this.failCallBack.length) this.failCallBack.shift()()
    }
    // 实现链式调用then
    
    then (successCallBack,failCallBack) {
        let promise2 = new MyPromise((res,rej)=>{
           
            if(this.status === FULFILLED){
               
                setTimeout(()=>{
                    try {
                    let x =   successCallBack(this.value)
                    //new 的过程中拿不到promise2 改成异步的就行了
                    resolvePromise(promise2,x,res,rej)
                    // res(x)
                // 判断 x 的值是普通值还是promise对象
                // 如果是普通值 直接调用resolve 
                // 如果是promise对象 查看promsie对象返回的结果 
                // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                    } catch (e) {
                        rej(e)
                    }
                   },0)
               
              }else if(this.status === REJECTED){
                 
                  setTimeout(()=>{
                    try {
                    let x =    failCallBack(this.reason)
                    //new 的过程中拿不到promise2 改成异步的就行了
                    resolvePromise(promise2,x,res,rej)
                    // res(x)
                // 判断 x 的值是普通值还是promise对象
                // 如果是普通值 直接调用resolve 
                // 如果是promise对象 查看promsie对象返回的结果 
                // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                    } catch (e) {
                        rej(e)
                    }
                   },0)
              }else{
                  // 如果status没改变说明 res和rej都没执行 先存起来
                  this.successCallBack.push(()=>{
                    setTimeout(()=>{
                        try {
                        let x =   successCallBack(this.value)
                        //new 的过程中拿不到promise2 改成异步的就行了
                        resolvePromise(promise2,x,res,rej)
                        // res(x)
                    // 判断 x 的值是普通值还是promise对象
                    // 如果是普通值 直接调用resolve 
                    // 如果是promise对象 查看promsie对象返回的结果 
                    // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                        } catch (e) {
                            rej(e)
                        }
                       },0)
                  })   
                  this.failCallBack.push(()=>{
                    setTimeout(()=>{
                        try {
                        let x =    failCallBack(this.reason)
                        //new 的过程中拿不到promise2 改成异步的就行了
                        resolvePromise(promise2,x,res,rej)
                        // res(x)
                    // 判断 x 的值是普通值还是promise对象
                    // 如果是普通值 直接调用resolve 
                    // 如果是promise对象 查看promsie对象返回的结果 
                    // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                        } catch (e) {
                            rej(e)
                        }
                       },0)
                  })   
              }
        });
        

        return promise2
    }
}
function resolvePromise(promise2,x,res,rej){
    if(promise2 === x){
        return rej(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    if(x instanceof MyPromise){
        x.then(res,rej)
     
    }else{
        res(x)
    }
}

module.exports = MyPromise
// const MyPromise = require('../myPromise')
const Mypromise = require('./myPromise')
// 


const my = new Mypromise((res,rej)=>{
//    throw new Error('fail')
    // res(2)
    setTimeout(()=>{
        res(1)
    },1500)
    // rej(2)
})

// function other (){
//     return new Mypromise((res,rej)=>{
//         res('other')
//     })
// }
let f = function fail(v){
    console.log('fail log1');
    console.log(v);
    // throw new Error('fail then')
    // return 33
}
let s = function success(v){
    console.log('success log1');
    console.log(v);
    return 2
    //  throw new Error('success then')
}

my.then(s,f)
.then(v => console.log(v),v => console.log(v))

success log1
1
2

将 then 方法的参数变成可选参数

const PENDING = 'pengding'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor(excecutor){
        try {
            excecutor(this.resolve,this.rejected)
        } catch (e) {
            this.rejected(e);
        }
    }
    status = PENDING
     // 成功之后的值
    value = undefined;
    // 失败后的原因
    reason = undefined;
    successCallBack = []
    failCallBack = []
    resolve = value =>{
        // statu改变了就不能再改变了 所以先判断一下
        if(this.status !== PENDING) return
       this.status = FULFILLED 
       this.value = value
    //    如果有就调用
    while(this.successCallBack.length) this.successCallBack.shift()()
    }
    
    rejected = value =>{
        if(this.status !== PENDING) return
        this.status = REJECTED 
        this.reason = value
        while(this.failCallBack.length) this.failCallBack.shift()()
    }
    // 实现链式调用then
    
    then (successCallBack,failCallBack) {
        successCallBack = successCallBack ? successCallBack : value => value
        failCallBack = failCallBack ? failCallBack : reason => {throw reason}
        let promise2 = new MyPromise((res,rej)=>{
           
            if(this.status === FULFILLED){
               
                setTimeout(()=>{
                    try {
                    let x =   successCallBack(this.value)
                    //new 的过程中拿不到promise2 改成异步的就行了
                    resolvePromise(promise2,x,res,rej)
                    // res(x)
                // 判断 x 的值是普通值还是promise对象
                // 如果是普通值 直接调用resolve 
                // 如果是promise对象 查看promsie对象返回的结果 
                // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                    } catch (e) {
                        rej(e)
                    }
                   },0)
               
              }else if(this.status === REJECTED){
                 
                  setTimeout(()=>{
                    try {
                    let x =    failCallBack(this.reason)
                    //new 的过程中拿不到promise2 改成异步的就行了
                    resolvePromise(promise2,x,res,rej)
                    // res(x)
                // 判断 x 的值是普通值还是promise对象
                // 如果是普通值 直接调用resolve 
                // 如果是promise对象 查看promsie对象返回的结果 
                // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                    } catch (e) {
                        rej(e)
                    }
                   },0)
              }else{
                  // 如果status没改变说明 res和rej都没执行 先存起来
                  this.successCallBack.push(()=>{
                    setTimeout(()=>{
                        try {
                        let x =   successCallBack(this.value)
                        //new 的过程中拿不到promise2 改成异步的就行了
                        resolvePromise(promise2,x,res,rej)
                        // res(x)
                    // 判断 x 的值是普通值还是promise对象
                    // 如果是普通值 直接调用resolve 
                    // 如果是promise对象 查看promsie对象返回的结果 
                    // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                        } catch (e) {
                            rej(e)
                        }
                       },0)
                  })   
                  this.failCallBack.push(()=>{
                    setTimeout(()=>{
                        try {
                        let x =    failCallBack(this.reason)
                        //new 的过程中拿不到promise2 改成异步的就行了
                        resolvePromise(promise2,x,res,rej)
                        // res(x)
                    // 判断 x 的值是普通值还是promise对象
                    // 如果是普通值 直接调用resolve 
                    // 如果是promise对象 查看promsie对象返回的结果 
                    // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                        } catch (e) {
                            rej(e)
                        }
                       },0)
                  })   
              }
        });
        

        return promise2
    }
}
function resolvePromise(promise2,x,res,rej){
    if(promise2 === x){
        return rej(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    if(x instanceof MyPromise){
        x.then(res,rej)
     
    }else{
        res(x)
    }
}

module.exports = MyPromise

结果

const my = new Mypromise((res,rej)=>{
//    throw new Error('fail')
    res('promise success')
    // setTimeout(()=>{
    //     res(1)
    // },1500)
    // rej(2)
})

my.then().then().then(v=> console.log(v),v=> console.log(v))
//promise success

Promise.all 方法的实现

All方法回顾:数组为参数,按顺序执行,有一个失败就都失败,直接返回数组结果,都成功返回所有数组结果
在这里插入图片描述
在这里插入图片描述
使用index 长度对比arr长度 如果相等,证明所有都执行完了
上代码

 static all (arr){
        let result = []
        let index = 0
      return  new MyPromise((res,rej)=>{
            function addResult(value,i){
                result[i] = value
                index++
                if(index === arr.length){
                    res(result)
                }
            }
            for(let i = 0; i < arr.length;i++){
                let current = arr[i]
                if(current instanceof MyPromise){
                    
                    current.then(value => addResult(value,i),reason =>rej(reason))
                }else{
                    addResult(current,i)
                }
            }
           
        })
      
    }

结果

let p1 = new MyPromise((res,rej)=>{
    setTimeout(()=>{
        res('p1')
    },1000)
})

let p2 = new MyPromise((res,rej)=>{
    // res('p2')
    rej('p2')
})
MyPromise.all(['12',p1,p2,'3']).then(v =>{console.log(v)},v =>{console.log(v)})
//p2

Promise.resolve 方法的实现

较简单就不贴其他代码了,判断是否是promise 是就返回,是普通值就new一个promise反回

   static resolve(v){
        if(v instanceof MyPromise) return v
        return new MyPromise((res,rej)=>{res(v)})
           
    }

let p1 = new MyPromise((res,rej)=>{
    setTimeout(()=>{
        res('p1')
    },1000)
})

let p2 = new MyPromise((res,rej)=>{
    // res('p2')
    rej('p2')
})
MyPromise.resolve(p1).then(res => console.log(res))
MyPromise.resolve('p12').then(res => console.log(res))

finally 方法的实现

   finally (callback){
        return this.then(value =>{
            return MyPromise.resolve(callback()).then(()=> value)
        }, reason =>{
            return MyPromise.resolve(callback()).then(()=> {throw reason})
        })
    }

catch 方法的实现

catch(failCallback){
       return this.then(undefined,failCallback)
    }

let p2 = new MyPromise((res,rej)=>{
    // res('p2')
    rej('p2')
})

p2.then(v=>console.log(2)).catch(v=>console.log(v)) //p2
/*
  1. Promise 就是一个类 在执行这个类的时候 需要传递一个执行器进去()=>{} 执行器会立即执行
  2. Promise 中有三种状态 分别为 成功 fulfilled 失败 rejected 等待 pending
    pending -> fulfilled
    pending -> rejected
    一旦状态确定就不可更改
  3. resolve和reject函数是用来更改状态的
    resolve: fulfilled
    reject: rejected
  4. then方法内部做的事情就判断状态 如果状态是成功 调用成功的回调函数 如果状态是失败 调用失败回调函数 then方法是被定义在原型对象中的
  5. then成功回调有一个参数 表示成功之后的值 then失败回调有一个参数 表示失败后的原因
  6. 同一个promise对象下面的then方法是可以被调用多次的
  7. then方法是可以被链式调用的, 后面then方法的回调函数拿到值的是上一个then方法的回调函数的返回值
*/

const MyPromise = require('./myPromise');

function p1 () {
  return new MyPromise(function (resolve, reject) {
    setTimeout(function () {
      resolve('p1')
    }, 2000)
  })
}
function p2 () {
  return new MyPromise(function (resolve, reject) {
    reject('失败')
    // resolve('成功');  
  })
}

p2()
  .then(value => console.log(value))
  .catch(reason => console.log(reason))

race方法实现

static race(arr){
        let mypro = new JackPromise((res,rej)=>{
            for(let i = 0;i<arr.length;i++){
                if(arr[i] instanceof JackPromise){
                    arr[i].then(res,rej)
                }else{
                    res(arr[i])
                }
            }
        })
        return mypro
    }
    JackPromise.race([p2,2]).then(v=>console.log(v))
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值