前端知识点——手写Promise

本文主要探讨前端知识点,深入解析Promise的实现原理。通过介绍Promise的构造函数和三种状态(pending, fulfilled, rejected),阐述了Promise如何确保状态不可逆,并讲解了then方法内部如何根据状态执行相应回调。" 134400533,12687275,KVM虚拟化技术详解与实践,"['Linux', 'CentOS', '运维', '虚拟化技术', '云计算']
摘要由CSDN通过智能技术生成

写在前面

笔记内容大多出自于拉勾教育大前端高薪训练营的教程,因此也许会和其他文章雷同较多,请担待。

Promise核心逻辑实现

  • Promise就是一个类,在执行这个类的时候需要传递一个执行器出去,执行器会立即执行
  • Promise有三种状态 -> pending fulfilled rejected
  • Promise一旦状态改变,则不会再改变
  • then方法内部就是判断状态,根据状态调用不同的回调
/* 简单版本-1 不支持异步情况 */
const PENDING = 'pending'
const FULFILLING = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
  state = PENDING
  value = undefined
  reason = undefined
  constructor(executor) {
    executor(this.resolve, this.reject)
  }
  /* 箭头函数区域 start */
  /* 这里箭头函数的作用是将函数体内的this指向当前类,因为在使用Promise的时候是直接resolve()/reject()的,所以这里的resolve/reject在没有箭头函数时是指向window的 */
  resolve = (value) => {
    if (this.state === PENDING) {
      this.state = FULFILLING
      this.value = value
    }
  }
  reject = (reason) => {
    if (this.state === PENDING) {
      this.state = REJECTED
      this.reason = reason
    }
  }
  /* 箭头函数区域 end */
  then(onFulfilledCallbacks, onRejectedCallbacks) {
    // 判断状态
    if (this.state === FULFILLING) {
      onFulfilledCallbacks(this.value)
    } else if (this.state === REJECTED) {
      onRejectedCallbacks(this.reason)
    }
  }
}
new MyPromise((resolve, reject) => {
  if (Math.random() > .5) {
    resolve('success')
  } else {
    reject('fail')
  }
}).then(
  res => {
    console.log('suc', res)
  },
  err => {
    console.log('err', err)
  }
)
/* 简单版本-2 支持异步情况 */
const PENDING = 'pending'
const FULFILLING = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
  state = PENDING
  value = undefined
  reason = undefined
  onFulfilledCallback = undefined
  onRejectedCallback = undefined
  constructor(executor) {
    executor(this.resolve, this.reject)
  }
  /* 箭头函数区域 start */
  /* 这里箭头函数的作用是将函数体内的this指向当前类,因为在使用Promise的时候是直接resolve()/reject()的,所以这里的resolve/reject在没有箭头函数时是指向window的 */
  resolve = (value) => {
    if (this.state === PENDING) {
      this.state = FULFILLING
      this.value = value
      this.onFulfilledCallback && this.onFulfilledCallback(this.value)
    }
  }
  reject = (reason) => {
    if (this.state === PENDING) {
      this.state = REJECTED
      this.reason = reason
      this.onRejectedCallback && this.onRejectedCallback(this.reason)
    }
  }
  /* 箭头函数区域 end */
  then(onFulfilledCallback, onRejectedCallback) {
    // 判断状态
    if (this.state === FULFILLING) {
      onFulfilledCallback(this.value)
    } else if (this.state === REJECTED) {
      onRejectedCallback(this.reason)
    } else {
      this.onFulfilledCallback = onFulfilledCallback
      this.onRejectedCallback = onRejectedCallback
    }
  }
}
new MyPromise((resolve, reject) => {
  if (Math.random() > .5) {
    setTimeout(() => {
      resolve('success')
    }, 2000)
  } else {
    setTimeout(() => {
      reject('fail')
    }, 2000)
  }
}).then(
  res => {
    console.log('suc', res)
  },
  err => {
    console.log('err', err)
  }
)
/* 进阶版本 支持异步情况且支持多次then处理结果,但都是对第一个Promise对象传递出的结果进行处理 */
const PENDING = 'pending'
const FULFILLING = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
  state = PENDING
  value = undefined
  reason = undefined
  onFulfilledCallbacks = []
  onRejectedCallbacks = []
  constructor(executor) {
    executor(this.resolve, this.reject)
  }
  /* 箭头函数区域 start */
  /* 这里箭头函数的作用是将函数体内的this指向当前类,因为在使用Promise的时候是直接resolve()/reject()的,所以这里的resolve/reject在没有箭头函数时是指向window的 */
  resolve = (value) => {
    if (this.state === PENDING) {
      this.state = FULFILLING
      this.value = value
      while(this.onFulfilledCallbacks.length) this.onFulfilledCallbacks.shift()(this.value)
    }
  }
  reject = (reason) => {
    if (this.state === PENDING) {
      this.state = REJECTED
      this.reason = reason
      while(this.onRejectedCallbacks.length) this.onRejectedCallbacks.shift()(this.reason)
    }
  }
  /* 箭头函数区域 end */
  then(onFulfilledCallback, onRejectedCallback) {
    // 判断状态
    if (this.state === FULFILLING) {
      onFulfilledCallback(this.value)
    } else if (this.state === REJECTED) {
      onRejectedCallback(this.reason)
    } else {
      this.onFulfilledCallbacks.push(onFulfilledCallback)
      this.onRejectedCallbacks.push(onRejectedCallback)
    }
  }
}
const p = new MyPromise((resolve, reject) => {
  if (Math.random() > .5) {
    setTimeout(() => {
      resolve('success')
    }, 2000)
  } else {
    setTimeout(() => {
      reject('fail')
    }, 2000)
  }
})
p.then(
  res => {
    console.log('suc-1', res)
  },
  err => {
    console.log('err-1', err)
  }
)
p.then(
  res => {
    console.log('suc-2', res)
  },
  err => {
    console.log('err-2', err)
  }
)
p.then(
  res => {
    console.log('suc-3', res)
  },
  err => {
    console.log('err-3', err)
  }
)
/* 进阶版本-2 支持多次then处理结果,并且每次then都是对前一个Promise对象传递出的结果进行处理,但在异步时会有问题 */
const PENDING = 'pending'
const FULFILLING = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
  state = PENDING
  value = undefined
  reason = undefined
  onFulfilledCallbacks = []
  onRejectedCallbacks = []
  constructor(executor) {
    executor(this.resolve, this.reject)
  }
  /* 箭头函数区域 start */
  /* 这里箭头函数的作用是将函数体内的this指向当前类,因为在使用Promise的时候是直接resolve()/reject()的,所以这里的resolve/reject在没有箭头函数时是指向window的 */
  resolve = (value) => {
    if (this.state === PENDING) {
      this.state = FULFILLING
      this.value = value
      while(this.onFulfilledCallbacks.length) this.onFulfilledCallbacks.shift()(this.value)
    }
  }
  reject = (reason) => {
    if (this.state === PENDING) {
      this.state = REJECTED
      this.reason = reason
      while(this.onRejectedCallbacks.length) this.onRejectedCallbacks.shift()(this.reason)
    }
  }
  /* 箭头函数区域 end */
  then(onFulfilledCallback, onRejectedCallback) {
    return new MyPromise((resolve, reject) => {
      // 判断状态
      if (this.state === FULFILLING) {
        resolve(onFulfilledCallback(this.value))
      } else if (this.state === REJECTED) {
        reject(onRejectedCallback(this.reason))
      } else {
        this.onFulfilledCallbacks.push(onFulfilledCallback)
        this.onRejectedCallbacks.push(onRejectedCallback)
      }
    })
  }
}
const p = new MyPromise((resolve, reject) => {
  if (Math.random() > .5) {
    setTimeout(() => {
      resolve('success-1')
    }, 2000)
  } else {
    setTimeout(() => {
      reject('fail-1')
    }, 2000)
  }
}).then(
  res => {
    console.log('suc-1', res)
    return 'success-2'
  },
  err => {
    console.log('err-1', err)
    return 'err-2'
  }
).then(
  res => {
    console.log('suc-2', res)
    return 'success-3'
  },
  err => {
    console.log('err-2', err)
    return 'success-3'
  }
).then(
  res => {
    console.log('suc-3', res)
  },
  err => {
    console.log('err-3', err)
  }
)
/* 进阶版本-3 支持多次then处理结果,并且每次then都是对前一个Promise对象传递出的结果进行处理,且在异步时没有问题 */
const PENDING = 'pending'
const FULFILLING = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
  state = PENDING
  value = undefined
  reason = undefined
  onFulfilledCallbacks = []
  onRejectedCallbacks = []
  constructor(executor) {
    try {
      executor(this.resolve, this.reject)
    } catch(e) {
      this.reject(e)
    }
  }
  /* 箭头函数区域 start */
  /* 这里箭头函数的作用是将函数体内的this指向当前类,因为在使用Promise的时候是直接resolve()/reject()的,所以这里的resolve/reject在没有箭头函数时是指向window的 */
  resolve = (value) => {
    if (this.state === PENDING) {
      this.state = FULFILLING
      this.value = value
      while(this.onFulfilledCallbacks.length) this.onFulfilledCallbacks.shift()()
    }
  }
  reject = (reason) => {
    if (this.state === PENDING) {
      this.state = REJECTED
      this.reason = reason
      while(this.onRejectedCallbacks.length) this.onRejectedCallbacks.shift()()
    }
  }
  /* 箭头函数区域 end */
  then(onFulfilledCallback, onRejectedCallback) {
    let promise2 =  new MyPromise((resolve, reject) => {
      onFulfilledCallback = onFulfilledCallback ? onFulfilledCallback : value => value
      onRejectedCallback = onRejectedCallback ? onRejectedCallback : reason => { throw reason }
      // 判断状态
      if (this.state === FULFILLING) {
        // 使用定时器是为了获取到promise2
        setTimeout(() => {
          try {
            let result = onFulfilledCallback(this.value)
            resolvePromise(promise2, result, resolve, reject)
          } catch(e) {
            reject(e)
          }
        })
      } else if (this.state === REJECTED) {
        // 使用定时器是为了获取到promise2
        setTimeout(() => {
          try {
            let result = onRejectedCallback(this.reason)
            resolvePromise(promise2, result, resolve, reject)
          } catch(e) {
            reject(e)
          }
        })
      } else {
        this.onFulfilledCallbacks.push(() => {
          // 使用定时器是为了获取到promise2
          setTimeout(() => {
            try {
              let result = onFulfilledCallback(this.value)
              resolvePromise(promise2, result, resolve, reject)
            } catch(e) {
              reject(e)
            }
          })
        })
        this.onRejectedCallbacks.push(() => {
          // 使用定时器是为了获取到promise2
          setTimeout(() => {
            try {
              let result = onRejectedCallback(this.reason)
              resolvePromise(promise2, result, resolve, reject)
            } catch(e) {
              reject(e)
            }
          })
        })
      }
    })
    return promise2
  }
}
function resolvePromise(promise2, result, resolve, reject) {
  // then中可能返回自身,所以需要做这一步判断阻止程序运行
  if (promise2 === result) return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
  if (result instanceof MyPromise) {
    // Promise对象
    result.then(
      res => {
        resolve(res)
      },
      err => {
        reject(err)
      }
    )
  } else {
    // 普通值
    resolve(result)
  }
}
const p = new Promise((resolve, reject) => {
  if (Math.random() > .5) {
    setTimeout(() => {
      resolve('success-1')
    }, 2000)
  } else {
    setTimeout(() => {
      reject('fail-1')
    }, 2000)
  }
}).then(
  res => {
    console.log('suc-1', res)
    return 'success-2'
  },
  err => {
    console.log('err-1', err)
    return 'fail-2'
  }
).then(
  res => {
    console.log('suc-2', res)
    return 'success-3'
  },
  err => {
    console.log('err-2', err)
    return 'fail-3'
  }
).then(
  res => {
    console.log('suc-3', res)
  },
  err => {
    console.log('err-3', err)
  }
)
/* 进阶版本-4 all方法、finally方法和catch方法 */
const PENDING = 'pending'
const FULFILLING = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
  state = PENDING
  value = undefined
  reason = undefined
  onFulfilledCallbacks = []
  onRejectedCallbacks = []
  constructor(executor) {
    try {
      executor(this.resolve, this.reject)
    } catch(e) {
      this.reject(e)
    }
  }
  /* 箭头函数区域 start */
  /* 这里箭头函数的作用是将函数体内的this指向当前类,因为在使用Promise的时候是直接resolve()/reject()的,所以这里的resolve/reject在没有箭头函数时是指向window的 */
  resolve = (value) => {
    if (this.state === PENDING) {
      this.state = FULFILLING
      this.value = value
      while(this.onFulfilledCallbacks.length) this.onFulfilledCallbacks.shift()()
    }
  }
  reject = (reason) => {
    if (this.state === PENDING) {
      this.state = REJECTED
      this.reason = reason
      while(this.onRejectedCallbacks.length) this.onRejectedCallbacks.shift()()
    }
  }
  /* 箭头函数区域 end */
  then(onFulfilledCallback, onRejectedCallback) {
    let promise2 =  new MyPromise((resolve, reject) => {
      onFulfilledCallback = onFulfilledCallback ? onFulfilledCallback : value => value
      onRejectedCallback = onRejectedCallback ? onRejectedCallback : reason => { throw reason }
      // 判断状态
      if (this.state === FULFILLING) {
        // 使用定时器是为了获取到promise2
        setTimeout(() => {
          try {
            let result = onFulfilledCallback(this.value)
            resolvePromise(promise2, result, resolve, reject)
          } catch(e) {
            reject(e)
          }
        })
      } else if (this.state === REJECTED) {
        // 使用定时器是为了获取到promise2
        setTimeout(() => {
          try {
            let result = onRejectedCallback(this.reason)
            resolvePromise(promise2, result, resolve, reject)
          } catch(e) {
            reject(e)
          }
        })
      } else {
        this.onFulfilledCallbacks.push(() => {
          // 使用定时器是为了获取到promise2
          setTimeout(() => {
            try {
              let result = onFulfilledCallback(this.value)
              resolvePromise(promise2, result, resolve, reject)
            } catch(e) {
              reject(e)
            }
          })
        })
        this.onRejectedCallbacks.push(() => {
          // 使用定时器是为了获取到promise2
          setTimeout(() => {
            try {
              let result = onRejectedCallback(this.reason)
              resolvePromise(promise2, result, resolve, reject)
            } catch(e) {
              reject(e)
            }
          })
        })
      }
    })
    return promise2
  }
  finally(callback) {
    return this.then(
      value => {
        return MyPromise.resolve(callback()).then(() => value)
      },
      reason => {
        return MyPromise.resolve(callback()).then(() => { throw reason })
      }
    )
  }
  catch(onRejectedCallback) {
    return this.then(undefined, onRejectedCallback)
  }
  static all(array) {
    let result = []
    let index = 0
    return new MyPromise((resolve, reject) => {
      function addData(key, value) {
        result[key] = value
        index++
        if (index === array.length - 1) resolve(result)
      }
      for (let i = 0; i < array.length; i++) {
        if (array[i] instanceof MyPromise) {
          array[i].then(res => addData(i, res), err => reject(err))
        } else {
          addData(i, array[i])
        }
      }
    })
  }
  static resolve(value) {
    if (value instanceof MyPromise) {
      return value
    } else {
      return new Promise(resolve => resolve(value))
    }
  }
}
function resolvePromise(promise2, result, resolve, reject) {
  // then中可能返回自身,所以需要做这一步判断阻止程序运行
  if (promise2 === result) return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
  if (result instanceof MyPromise) {
    // Promise对象
    result.then(
      res => {
        resolve(res)
      },
      err => {
        reject(err)
      }
    )
  } else {
    // 普通值
    resolve(result)
  }
}
const p = new Promise((resolve, reject) => {
  if (Math.random() > .5) {
    setTimeout(() => {
      resolve('success-1')
    }, 2000)
  } else {
    setTimeout(() => {
      reject('fail-1')
    }, 2000)
  }
}).then(
  res => {
    console.log('suc-1', res)
    return 'success-2'
  },
  err => {
    console.log('err-1', err)
    return 'fail-2'
  }
).then(
  res => {
    console.log('suc-2', res)
    return 'success-3'
  },
  err => {
    console.log('err-2', err)
    return 'fail-3'
  }
).then(
  res => {
    console.log('suc-3', res)
  },
  err => {
    console.log('err-3', err)
  }
)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值