手写Promise

前言

为解决回调地狱问题,提出了 Promise 对象,并且后来加入了 ES6 标准。

一、Promise是什么?

Promise对象的then方法返回新的Promise对象,支持链式调用,解决了回调地狱的问题。

二、手写Promise(构造函数版本)

function Promise (executor) {
  this.PromiseState = 'pending'
  this.PromiseResult = null
  const self = this
  this.callbacks = []

  function resolve (data) {
    if (self.PromiseState === 'pending') {
      self.PromiseState = 'fulfilled'
      self.PromiseResult = data
      setTimeout(() => {
        self.callbacks.forEach(item=>item.onresolved(data))
      })
    }
    
  }
  function reject (reason) {
    if (self.PromiseState === 'pending') {
      self.PromiseState = 'rejected'
      self.PromiseResult = reason
      setTimeout(() => {
        self.callbacks.forEach(item=>item.onrejected(reason))
        
      });

    }
    
  }
  try {
    executor(resolve,reject)
  } catch (e) {
    reject(e) 
  }
  
}
Promise.prototype.then = function (onresolved, onrejected) {
  return new Promise((resolve, reject) => {
    const self = this
    if (typeof onrejected !== 'function') {
      onrejected = reason => { throw reason }
    }
    if (typeof onresolved !== 'function') {
      onresolved = value => value
    }
    const callback = function (type) {
      try {
        const result = type(self.PromiseResult)
        if (result instanceof Promise) {
          result.then(v => { 
            resolve(v)
          }, r => {
            reject(r)
          })
          
        } else {
          resolve(result)
        }
      } catch (e) {
        reject(e)
        
      }
    }
    if (this.PromiseState === 'fulfilled') {
      setTimeout(() => {
        callback(onresolved)
      })
      
    }
    if (this.PromiseState === 'rejected') {
      setTimeout(() => {
        callback(onrejected)
      })
    }
    if (this.PromiseState === 'pending') {
       this.callbacks.push({
         onresolved: function () {
          callback(onresolved)
      },
         onrejected: function () {
          callback(onrejected)
      }
      })
    }
  })

 
  
}

Promise.prototype.catch = function (onrejected) {
  return this.then(undefined,onrejected)
}

Promise.resolve = function (data) {
  return new Promise((resolve, reject) =>{
    if (data instanceof Promise) {
      data.then(v => { 
        resolve(v)
      }, r => {
        reject(r)
      })
    } else {
      resolve(data)
    }
  })
}

Promise.reject = function (data) {
  return new Promise((resolve, reject) => {
    reject(data)
  })
}

Promise.all = function (promises) {
  return new Promise((resolve, reject) => {
    let count = 0
    let result = []
    for (let i = 0; i < promises.length; i++){
      promises[i].then(v => {
        count++
        result[i] = v
        if (count === promises.length) {
          resolve(result)
        }
      }, r => {
        reject(r)
      })
    }
  })
}

Promise.race = function (promises) {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < promises.length; i++){
      promises[i].then(v => {
        resolve(v)
      }, r => {
        reject(r)
      })
    }
  })
}

三、手写Promise(class版本)

class Promise{
  constructor(executor) {
    this.PromiseState = 'pending'
    this.PromiseResult = null
    this.callbacks = []

    const resolve= (data)=> {
      if (this.PromiseState === 'pending') {
        this.PromiseState = 'fulfilled'
        this.PromiseResult = data
        setTimeout(() => {
          this.callbacks.forEach(item=>item.onresolved(data))
        })
      }
      
    }
    const reject =  (reason)=> {
      if (this.PromiseState === 'pending') {
        this.PromiseState = 'rejected'
        this.PromiseResult = reason
        setTimeout(() => {
          this.callbacks.forEach(item=>item.onrejected(reason))
        });
      }
    }
    try {
      executor(resolve,reject)
    } catch (e) {
      reject(e) 
    }
  }
  then (onresolved, onrejected) {
    return new Promise((resolve, reject) => {
      const self = this
      if (typeof onrejected !== 'function') {
        onrejected = reason => { throw reason }
      }
      if (typeof onresolved !== 'function') {
        onresolved = value => value
      }
      const callback = type=> {
        try {
          const result = type(self.PromiseResult)
          if (result instanceof Promise) {
            result.then(v => { 
              resolve(v)
            }, r => {
              reject(r)
            })
            
          } else {
            resolve(result)
          }
        } catch (e) {
          reject(e)
          
        }
      }
      if (this.PromiseState === 'fulfilled') {
        setTimeout(() => {
          callback(onresolved)
        })
      }
      if (this.PromiseState === 'rejected') {
        setTimeout(() => {
          callback(onrejected)
        })
      }
      if (this.PromiseState === 'pending') {
         this.callbacks.push({
           onresolved: function () {
            callback(onresolved)
        },
           onrejected: function () {
            callback(onrejected)
        }
        })
      }
    })
  }
 catch (onrejected) {
    return this.then(undefined,onrejected)
  }
  static resolve(data) {
    return new Promise((resolve, reject) =>{
      if (data instanceof Promise) {
        data.then(v => { 
          resolve(v)
        }, r => {
          reject(r)
        })
      } else {
        resolve(data)
      }
    })
  }
  static reject(data) {
    return new Promise((resolve, reject) => {
      reject(data)
    })
  }
  static all(promises) {
    return new Promise((resolve, reject) => {
      let count = 0
      let result = []
      for (let i = 0; i < promises.length; i++){
        promises[i].then(v => {
          count++
          result[i] = v
          if (count === promises.length) {
            resolve(result)
          }
        }, r => {
          reject(r)
        })
      }
    })
  }
  static race(promises) {
    return new Promise((resolve, reject) => {
      for (let i = 0; i < promises.length; i++){
        promises[i].then(v => {
          resolve(v)
        }, r => {
          reject(r)
        })
      }
    })
  }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值