自己简单封装一个promise

Promise封装

一、ES5 构造函数版

Promise对象

/**
 * promise封装 es5版本
 */
function Mypromise (callback) {
  const _this = this
  this.value = undefined
  this.status = 'pending'
  // 异步支持
  this.resQueues = []
  this.rejQueues = []
  // 代码执行异常处理(注意对于函数中异步代码执行异常无法检测到)
  try {
    callback(resolve, reject)
  } catch (e) {
    reject(e)
  }

  function resolve (value) {
    // 使用setTimeout保证异步执行
    setTimeout(function () {
      if (_this.status === 'pending') {
        _this.status = 'fulfilled'
        _this.value = value
        // 遍历执行所有异步的成功处理函数
        _this.resQueues.forEach(cbItem => {
          cbItem()
          _this.resQueues.shift()
        })
      }
    })
  }

  function reject (value) {
    // 使用setTimeout保证异步执行
    setTimeout(function () {
      if (_this.status === 'pending') {
        _this.status = 'rejected'
        _this.value = value
        // 遍历执行所有异步的失败处理函数
        _this.rejQueues.forEach(cbItem => {
          cbItem()
          _this.rejQueues.shift()
        })
      }
    })
  }
} 

 

Promise.prototype.then()

// 链式 + 异步支持
Mypromise.prototype.then = function (resolveCallback, rejectCallback) {
  const _this = this
  return new Mypromise(function (resolve, reject) {
    if (_this.status === 'fulfilled') {
      resolveHandle()
    }
    if (_this.status === 'rejected') {
      rejectHandle()
    }
    if (_this.status === 'pending') {
      _this.resQueues.push(resolveHandle)
      _this.rejQueues.push(rejectHandle)
    }

    // then 成功回调处理
    function resolveHandle () {
      var result = resolveCallback instanceof Function && resolveCallback(_this.value) || _this.value
      if (result instanceof Mypromise) {
        result.then(resolve, reject)
      } else {
        resolve(result)
      }
    }
    // then 失败回调处理
    function rejectHandle () {
      var result = ejectCallback instanceof Function && rejectCallback(_this.value) || this.value
      if (result instanceof Mypromise) {
        result.then(resolve, reject)
      } else {
        reject(result)
      }
    }
  })
}

 

Promise.resolve()

// 参数如果是promise直接返回,否则返回fulfilled状态的promise
Mypromise.resolve = function (arg) {
  if (arg instanceof Mypromise) {
    return arg
  } else {
    return new Mypromise(function (resolve, reject) {
      resolve(arg)
    })
  }
}

 

Promise.reject()

// 参数如果是promise直接返回,否则返回rejected状态的promise
Mypromise.reject = function (arg) {
  if (arg instanceof Mypromise) {
    return arg
  } else {
    return new Mypromise(function (resolve, reject) {
      reject(arg)
    })
  }
}

 

Promise.all()

// 所有promise项都成功时返回,返回结果是所有项resolve结果的数组集合
// 一旦有一个失败就会返回失败,结果是失败promised的结果
Mypromise.all = function (iterable) {
  if (!Array.isArray(iterable)) {
    throw new TypeError('参数必须是一个数组')
  }
  return new Mypromise(function (resolve, reject) {
    var result = []
    var count = 0
    var fail = false
    iterable.forEach(function (item, index) {
      Mypromise.resolve(item).then(function (data) {
        result[index] = data
        count++
        // 保证result中结果顺序和iterable数组顺序一致
        if (!fail && count === iterable.length) {
          resolve(result)
        }
      }, function (err) {
        fail = true
        reject(err)
      })
    })
  })
}

 

Promise.race()

// 一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝
Mypromise.race = function (iterable) {
  if (!Array.isArray(iterable)) {
    throw new TypeError('参数必须是一个数组')
  }
  return new Mypromise(function (resolve, reject) {
    var done = false
    for (const item of iterable) {
      Mypromise.resolve(item).then(data => {
        if (!done) {
          resolve(data)
          done = true
        }
      }, err => {
        if (!done) {
          reject(err)
          done = true
        }
      })
    }
  })
}

 

 

二、ES6 class版

待补充

-------------smlie

参考:

https://segmentfault.com/a/1190000018116310

https://segmentfault.com/a/1190000018420228

posted @ 2020-09-07 19:13  Walker-lyl  阅读(502)  评论(0编辑  收藏  举报