Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

手动实现一个Promise #5

Open
sanjings opened this issue Sep 21, 2020 · 0 comments
Open

手动实现一个Promise #5

sanjings opened this issue Sep 21, 2020 · 0 comments

Comments

@sanjings
Copy link
Owner

sanjings commented Sep 21, 2020

手动实现一个Promise

Promise简单说明

  • Promise主要用于解决异步回调的问题
  • 存在三个状态(state)pending、fulfilled、rejected
  • pending(等待态)为初始态,并可以转化为fulfilled(成功态)和rejected(失败态),状态一旦变化,就不会再更改

实现思路

  • 使用ES6 class声明一个类
  • 接受一个fn函数作为参数,并且这个函数会在实例化时被执行
  • 定义value为成功时的值,reason为失败时的值
  • fn函数接收两个函数参数,一个用于改变成功态(resolve),一个用于改变失败态(reject)
  • 当resolve或reject在异步函数中执行时,由于then优先于resolve或reject执行,这时state还是pending, 所以将他们的在then里面的回调处理函数存放起来,一旦异步结束后调用resolve或者reject时,就执行他们各自的回调处理函数

以下是实现代码

class MyPromise {
  constructor(fn) {
    if (!fn || typeof(fn) !== 'function') {
      throw new Error('需要传入函数作为参数')
    }

    this.state = 'pending' // 初始化状态
    this.value = null // resolve成功的值
    this.reason = null // reject失败的值
    this.resolveCallbacks = [] // 存放成功的回调数组
    this.rejectCallbacks = [] // 存放失败的回调数组

    const resolve = value => {
      if (this.state === 'pending') {
        this.state = 'fulfilled'
        this.value = value;
        this.resolveCallbacks.forEach(cb => cb(value))
      }
    }

    const reject = reason => {
      if (this.state === 'pending') {
        this.state = 'rejected'
        this.reason = reason
        this.rejectCallbacks.forEach(cb => cb(reason))
      }
    }

    try{
      fn(resolve, reject)
    } catch (err) {
      reject(err)
    }
  }

  then(onResolve, onReject) {
    onResolve = typeof(onResolve) === 'function' ? onResolve : value => value;
    onReject = typeof(onReject) === 'function' ? onReject : reason => reason;
    
    switch(this.state) {
      // resolve或者reject在异步函数中执行时,state还是pendding状态,将他们的回调处理函数先保存,一旦resolve或者reject时,就调用
      case 'pending':
        this.resolveCallbacks.push(onResolve); // 将成功的回调存到resolveCallbacks里面
        this.rejectCallbacks.push(onReject) // 将失败的回调存到rejectCallbacks里面
        break;
      case 'fulfilled': 
        onResolve(this.value)
        break;
      case 'rejected':
        onReject(this.reason)
        break;
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant