美文网首页
用typescript实现Promise

用typescript实现Promise

作者: No_24 | 来源:发表于2020-03-22 23:39 被阅读0次

    已实现的api:

    • Promise2类
    • Promise2.all()
    • Promise2.race()
    • Promise2.resolve()
    • Promise2.reject()
    • Promise2.prototype.then()
    • Promise2.prototype.catch()
    • Promise2.prototype.finally()

    话不多说,直接上源码:

    type OnFulfilled = (value: any) => any
    type OnRejected = (reason: any) => any
    type OnFinally = () => void
    type Resolve = (value?: any) => void
    type Reject = (reason?: any) => void
    type Executor = (resolve: Resolve, reject: Reject) => any
    type FulfillObj = {
      onFulfilled?: OnFulfilled,
      resolve: Resolve,
      reject: Reject
    }
    type RejectObj = {
      onRejected?: OnRejected,
      resolve: Resolve,
      reject: Reject
    }
    type FinallyObj = {
      onFinally?: OnFinally,
      resolve: Resolve,
      reject: Reject
    }
    
    export class Promise2 {
      state: 'pending' | 'fulfilled' | 'rejected' = 'pending'
      private __fulfilled__: FulfillObj[] = []
      private __rejected__: RejectObj[] = []
      private __finally__: FinallyObj[] = []
      private __value__: any = null
    
      constructor(exacutor: Executor) {
        const resolve: Resolve = value => {
          if (value && typeof value.then === 'function') {
            value.then(resolve, reject)
          } else {
            if (this.state !== 'pending') return
            this.state = 'fulfilled'
            this.__value__ = value
            setTimeout(() => {
              this.__fulfilled__.forEach(obj => {
                if (typeof obj.onFulfilled === 'function') {
                  try {
                    const result = obj.onFulfilled(value)
                    if (result && typeof result.then === 'function') {
                      result.then(obj.resolve, obj.reject)
                    } else {
                      obj.resolve(result)
                    }
                  } catch (error) {
                    obj.reject(error)
                  }
                } else {
                  obj.resolve(value)
                }
              })
              callFinally()
            }, 0)
          }
    
        }
        const reject: Reject = reason => {
          if (this.state !== 'pending') return
          this.state = 'rejected'
          this.__value__ = reason
          setTimeout(() => {
            this.__rejected__.forEach(obj => {
              if (typeof obj.onRejected === 'function') {
                try {
                  const result = obj.onRejected(reason)
                  if (result && typeof result.then === 'function') {
                    result.then(obj.resolve, obj.reject)
                  } else {
                    obj.resolve(result)
                  }
                } catch (error) {
                  obj.reject(error)
                }
              } else {
                obj.reject(reason)
              }
            })
            callFinally()
          }, 0)
        }
        const callFinally = () => {
          this.__finally__.forEach(obj => {
            if (typeof obj.onFinally === 'function') {
              obj.onFinally()
            }
            if (this.state === 'fulfilled') {
              obj.resolve(this.__value__)
            } else {
              obj.reject(this.__value__)
            }
          })
        }
        try {
          exacutor(resolve, reject)
        } catch (error) {
          reject(error)
        }
      }
    
      then(onFulfilled?: OnFulfilled, onRejected?: OnRejected) {
        return new Promise2((resolve, reject) => {
          this.__fulfilled__.push({
            onFulfilled,
            resolve,
            reject
          })
          this.__rejected__.push({
            onRejected,
            resolve,
            reject
          })
        })
      }
    
      catch(onRejected?: OnRejected) {
        return new Promise2((resolve, reject) => {
          this.__rejected__.push({
            onRejected,
            resolve,
            reject
          })
        })
      }
    
      finally(onFinally?: OnFinally) {
        return new Promise2((resolve, reject) => {
          this.__finally__.push({
            onFinally,
            resolve,
            reject
          })
        })
      }
    
      static all(list: Promise2[]) {
        const results: any[] = []
        return new Promise2((resolve, reject) => {
          list.forEach(p => {
            p.then(
              value => {
                results.push(value)
                if (results.length === list.length) {
                  resolve(results)
                }
              }, reason => {
                reject(reason)
              })
          })
        })
      }
    
      static race(list: Promise2[]) {
        return new Promise2((resolve, reject) => {
          list.forEach(p => {
            p.then(
              value => {
                resolve(value)
              },
              reason => {
                reject(reason)
              }
            )
          })
        })
      }
    
      static reject(value?: any) {
        return new Promise2((resolve, reject) => {
          reject(value)
        })
      }
    
      static resolve(value?: any) {
        return new Promise2((resolve, reject) => {
          if (value && typeof value.then === 'function') {
            value.then(resolve, reject)
          } else {
            resolve(value)
          }
        })
      }
    }
    
    export default Promise2
    

    具体api是按MDN上Promise的api描述和Promises/A+规范来实现的,基本上测试通过了,大概花了一个下午的时间。

    github仓库--Promise的简单实现

    参考:

    1. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
    2. https://promisesaplus.com/

    相关文章

      网友评论

          本文标题:用typescript实现Promise

          本文链接:https://www.haomeiwen.com/subject/bcnbyhtx.html