手写promise过程

  1. 第一版
<!DOCTYPE html>

<div>手写promise</div>

<script>
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
 constructor(executor){
   executor(this.resolve, this.reject)
 }
 state = PENDING
 res = null
 err = null

 resolve = (r) => {
   if(this.state === PENDING){
     this.state = FULFILLED
     this.res = r
   }
 }
 reject = (e) => {
   if (this.state === PENDING) {
     this.state = REJECTED
     this.err = e
   }
 }

 then(onFulFilled,onRejected){
   if(this.state === FULFILLED){
     onFulFilled(this.res)
   } else if(this.state === REJECTED){
     onRejected(this.err)
   }
 }
}


var prmosise = new MyPromise((resolve,reject)=>{
 resolve('SUCCESS')
 reject('ERROR')
})
prmosise.then(res=>{
 console.log('resolve',res)
},err=>{
  console.log('reject',err)
})

</script>

在这里插入图片描述

var prmosise = new MyPromise((resolve,reject)=>{
  setTimeout(res=>{
   resolve('SUCCESS')// 此时加异步无法执行 因为then是立即执行函数 会导致主线程走完在调取setTimeout,此时的state是pending ,resolve无法返回值,所以resolve里面要执行缓存的reaolveCallback函数
  },2000)
})
prmosise.then(res=>{
  console.log('resolve',res)
},err=>{
   console.log('reject',err)
})

无输出

此时加异步无法执行 因为then是立即执行函数 会导致主线程走完在调取setTimeout,此时的state是pending ,resolve无法返回值,所以resolve里面要执行缓存的reaolveCallback函数

  1. 第二版,<支持异步逻辑>
<script>
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
  constructor(executor){
    executor(this.resolve, this.reject)
  }
  state = PENDING
  res = null
  err = null
  onFulFilledCallback = null
  onRejectedCallback = null

  resolve = (r) => {
    if(this.state === PENDING){
      this.state = FULFILLED
      this.res = r
      this.onFulFilledCallback && this.onFulFilledCallback(r)
    }
  }
  reject = (e) => {
    if (this.state === PENDING) {
      this.state = REJECTED
      this.err = e
      this.onRejectedCallback && this.onRejectedCallback(e)
    }
  }

  then(onFulFilled,onRejected){
    if(this.state === FULFILLED){
      onFulFilled(this.res)
    } else if(this.state === REJECTED){
      onRejected(this.err)
    } else if (this.state === PENDING){ // 缓存resolve和reject方法,为了异步使用
      this.onFulFilledCallback = onFulFilled
      this.onRejectedCallback = onRejected
    }
  }
}


var prmosise = new MyPromise((resolve,reject)=>{
  setTimeout(res=>{
   resolve('SUCCESS')
  },2000)
})
prmosise.then(res=>{
  console.log('resolve',res) // 输出resolve SUCCESS
},err=>{
   console.log('reject',err)
})

</script>

使用第二版的执行以下逻辑

var promise = new MyPromise((resolve,reject)=>{
  setTimeout(res=>{
   resolve('SUCCESS')
  },2000)
})
  promise.then(value => {
    console.log(1)
    console.log('resolve', value)
  })

  promise.then(value => {
    console.log(2)
    console.log('resolve', value)
  })

  promise.then(value => {
    console.log(3)
    console.log('resolve', value)
  })

输出
3
promise.html:64 resolve SUCCESS
为什么 1,2丢了呢?因为最后一次的then方法会把前两次的覆盖掉
如何实现都出来呢?那就需要把之前的两次的方法给缓存起来

  1. 第三版 <实现then方法多次条用添加多个处理函数>
<script>
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
  constructor(executor){
    executor(this.resolve, this.reject)
  }
  state = PENDING
  res = null
  err = null
  onFulFilledCallbacks = []
  onRejectedCallbacks = []

  resolve = (r) => {
    if(this.state === PENDING){
      this.state = FULFILLED
      this.res = r
      this.onFulFilledCallbacks.forEach(itemFun => {
        itemFun && itemFun(r)
      })
    }
  }
  reject = (e) => {
    if (this.state === PENDING) {
      this.state = REJECTED
      this.err = e
      this.onRejectedCallbacks.forEach(itemFun => {
        itemFun && itemFun(e)
      });
    }
  }

  then(onFulFilled,onRejected){
    if(this.state === FULFILLED){
      onFulFilled(this.res)
    } else if(this.state === REJECTED){
      onRejected(this.err)
    } else if (this.state === PENDING){ // 缓存resolve和reject方法,为了异步使用
      this.onFulFilledCallbacks.push(onFulFilled)
      this.onRejectedCallbacks.push(onRejected)
    }
  }
}


var promise = new MyPromise((resolve,reject)=>{
  setTimeout(res=>{
   resolve('SUCCESS')
  },2000)
})
  promise.then(value => {
    console.log(1)
    console.log('resolve', value)
  })

  promise.then(value => {
    console.log(2)
    console.log('resolve', value)
  })

  promise.then(value => {
    console.log(3)
    console.log('resolve', value)
  })

</script>

在这里插入图片描述

使用第三版无法处理then链式调用的问题
如下

var promise = new MyPromise((resolve,reject)=>{
  resolve('success')
}).then(value => {
  return new MyPromise((resolve, reject) => {
    resolve('1')
  })
}).then(value => {
  return new MyPromise((resolve, reject) => {
    resolve('2')
  })
}).then(value => {
  return new MyPromise((resolve, reject) => {
    resolve('3')
  })
})

在这里插入图片描述
在这里插入图片描述

因为之前写的then都是一个立即执行函数 并不是又返回一个promise
接下来我们来实现它

  1. 第四版 <实现then的链式调用>
    需要知道链式调用的原理 :
    即then返回一个promise
<script>
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
  constructor(executor){
    executor(this.resolve, this.reject)
  }
  state = PENDING
  res = null
  err = null
  onFulFilledCallbacks = []
  onRejectedCallbacks = []

  resolve = (r) => {
    if(this.state === PENDING){
      this.state = FULFILLED
      this.res = r
      this.onFulFilledCallbacks.forEach(itemFun => {
        itemFun && itemFun(r)
      })
    }
  }
  reject = (e) => {
    if (this.state === PENDING) {
      this.state = REJECTED
      this.err = e
      this.onRejectedCallbacks.forEach(itemFun => {
        itemFun && itemFun(e)
      });
    }
  }

  then(onFulFilled,onRejected){
    // if(this.state === FULFILLED){
    //   onFulFilled(this.res)
    // } else if(this.state === REJECTED){
    //   onRejected(this.err)
    // } else if (this.state === PENDING){ // 缓存resolve和reject方法,为了异步使用
    //   this.onFulFilledCallbacks.push(onFulFilled)
    //   this.onRejectedCallbacks.push(onRejected)
    // }
    return new MyPromise((resolve, reject) => {
      debugger
      if(this.state === FULFILLED){
        const x = onFulFilled(this.res)
        resolvePrmiseFun(x, resolve, reject) // 集中处理
      } else if(this.state === REJECTED){
        onRejected(this.err)
      } else if (this.state === PENDING) {
        this.onFulFilledCallbacks.push(onFulFilled)
        this.onRejectedCallbacks.push(onRejected)
      }
    })
  }
}
function resolvePrmiseFun(x, resolve, reject){
  // 判断x是不是 MyPromise 实例对象
  if(x instanceof MyPromise){
    x.then(resolve, reject)
  } else {
    resolve(x)
  }
}


var promise = new MyPromise((resolve,reject)=>{
  resolve('success')
}).then(value => {
  return new MyPromise((resolve, reject) => {
    console.log('resolve',value)
    resolve('1')
  })
}).then(value => {
  return new MyPromise((resolve, reject) => {
    console.log('resolve', value)
    resolve('2')
  })
}).then(value => {
  return new MyPromise((resolve, reject) => {
    console.log('resolve', value)
    resolve('3')
  })
})

</script>

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值