自定义封装promise和promise相关的方法

Promise 是一门新的技术(ES6 规范)

Promise 是 JS 中进行异步编程的新解决方案(旧方案是单纯使用回调函数)

Promise 很好的解决了回调地狱的问题 加强了代码的可阅读性

学习地址:https://www.bilibili.com/video/BV1GA411x7z1

添加了一些我自己的理解的注释  (#^.^#) 


function Promise(executor) {
  this.PromiseState = 'peding' // 默认状态是pedding
  this.PromiseResult = undefined
  this.callbacks = []
  let that = this
  function resolve(data) {
    if (that.PromiseState !== 'peding') return // 状态只能由peding转为其他状态
    that.PromiseResult = data // 改变结果
    that.PromiseState = 'fulfilled' // 改变状态
    // 改变状态之后执行传入的onResolved, onRejected函數
    // 存在多个回调的话需要全部都打印则需要使用数组
    // 循环将保存的onResolved, onRejected全都执行
    // 添加微任务
    queueMicrotask(() => {
      that.callbacks.forEach((item) => {
        item.onResolved(data)
      })
    });
    return data
  }
  function reject(data) {
    if (that.PromiseState !== 'peding') return // 状态只能由peding转为其他状态
    that.PromiseResult = data // 改变结果
    that.PromiseState = 'rejected' // 改变状态
    // 改变状态之后执行传入的onResolved, onRejected函數
    // 存在多个回调的话需要全部都打印则需要使用数组
    // 循环将保存的onResolved, onRejected全都执行
    // 添加微任务
    queueMicrotask(() => {
      that.callbacks.forEach((item) => {
        item.onRejected(data)
      })
    });
    return data
  }
  // 使用throw的时候返回状态直接为reject
  try {
    executor(resolve, reject)
  } catch(e) {
    reject(e)
  }
}

// then的返回值也是promise
// 传入then的方法是异步执行的
// then 返回值由传入的onResolved, onRejected的值决定
// 如果返回的是非 Promise 类型的对象 则状态是fulfilled 值是返回的值
// 如果是throw 抛出错误 则状态是rejected 值是返回的值
// 如果返回结果是 Promise 对象 则then的结果由Promise 的返回结果决定
Promise.prototype.then = function(onResolved, onRejected) {
  // 可能不传onRejected 或者onRejected 不是一个函数
  // 自定义一个函数 向下异常 因为catch的状态就是rejected
  if (typeof onRejected !== 'function') {
    onRejected = params => {
      throw params;
    }
  }
  // 可能不传onResolved  需要自定义一个onResolved函数
  if (typeof onResolved !== 'function') {
    onResolved = (value)=>{ return value; }
  }
  return new Promise((resolve, reject) => {
    let that = this
    // 封装处理函数
    function handleCallback(callbackType) {
      // 如果是throw 抛出错误 则状态是rejected 值是返回的值
      try {
        let result = callbackType(that.PromiseResult)
        // 如果返回结果是 Promise 对象 则then的结果由Promise 的返回结果决定
        if(result instanceof Promise) {
          result.then((v) => {
            resolve(v)
          }, (r) => {
            reject(r)
          })
        } else {
          // 如果返回的是非 Promise 类型的对象 则状态是fulfilled 值是返回的值
          resolve(result)
        }
      } catch (error) {
        reject(error)
      }
    }
    // 成功执行onResolved 拿到new Promise 实例的输出的值之后用来传到onResolved里面
    if (this.PromiseState === 'fulfilled') {
      // setTimeout(() => {
      //   handleCallback(onResolved)
      // })
      // 添加微任务
      queueMicrotask(() => {
        handleCallback(onResolved)
      });
    }
    // onRejected 拿到new Promise onRejected
    if (this.PromiseState === 'rejected') {
      // setTimeout(() => {
      //   handleCallback(onRejected)
      // })
      // 添加微任务
      queueMicrotask(() => {
        handleCallback(onRejected)
      });
    }
    // new promise内部是异步的时候执行then的时候状态还未改变
    // onResolved, onRejected函数需要放在状态改变之后执行 
    // 状态如果不改变 拿不到new Promise 输出的值
    if (this.PromiseState === 'peding') {
      // 将onResolved和onRejected保存 等到状态改变的时候在调用
      this.callbacks.push({
        onResolved: function(value) {
          handleCallback(onResolved)
        },
        onRejected: function() {
          handleCallback(onRejected)
        }
      })
    }
  })
}

// 添加 catch 方法
// catch是指定失败的一个回调函数   他的返回值是一个promise对象
Promise.prototype.catch = function(onRejected) {
  return this.then(undefined, onRejected)
}


// 添加 resolve 方法
// 方法返回一个promise对象
// 状态由传入的promise的值决定
// 如果传入的是一个非promise类型的数据、则状态是成功、返回的值是传入的值
// 如果传入的是一个promise类型的结构、则返回的结果由传入的promise的返回结果决定
//    例如:传入的是new Promise 返回值是成功,则Promise.resolve的返回结果也是成功
//          反之则失败
Promise.resolve = function(params) {
  return new Promise((resolve, reject) => {
    // 传入的是一个promise类型的结构
    if (params instanceof Promise) {
      params.then(v => {
        resolve(v)
      }, (j) => {
        reject(j)
      })
    } else {
      resolve(params)
    }
  })
}

// 添加 reject 方法
// reject的返回也是一个promise对象
Promise.reject = function(params) {
  return new Promise((resolve, reject) => {
    reject(params)
  })
}


// 添加 all 方法
// 返回的结果是一个promise对象
// 参数是一个promise组成的数组
// 结果由promise数组的返回状态决定
// 如果全部成功则返回的结果就是成功、返回的结果为传入的promise的对象的成功结果组成的数组
// 顺序是一一对应的
// 如果存在一个失败的、返回的是一个失败的promise对象、且返回的结果是那个失败的promise结果
Promise.all = function(arr) {
  return new Promise((resolve, reject) => {
    let results = []
    let cunt = 0
    arr.forEach((item, index) => {
      // 应当是由promise组成的数组
      if (item instanceof Promise) {
        item.then((v) => {
          results[index] = v
          cunt++
          // 这样是错的 因为[p1, p2, p3] 如果P1是异步的 
          // 会先results[1] = v results的length为2 results.length === arr.length为真
          // if (results.length === arr.length) {
          if (results.length === cunt) {
            resolve(results)
          }
        }, (j) => {
          reject(j)
        })
      }
    })
  })
}


// 添加 race 方法
// 接受一个由promise组成的数组
// 返回的是一个promise对象
// 返回的结果的状态由传入的数组中最先改变状态的promise决定
// race返回的结果的值就是最先改变状态的promise的结果值
Promise.race = function(arr) {
  return new Promise((resolve, reject) => {
    arr.forEach((item) => {
      item.then((v) => {
        resolve(v)
      }, (j) => {
        reject(j)
      })
    })
  })
}

测试代码




  
  
  
  Document
  


  

输出顺序为自定义封装promise和promise相关的方法_第1张图片

官方的输出顺序为自定义封装promise和promise相关的方法_第2张图片

和官方输出的结果一致(*^▽^*)

 

 

你可能感兴趣的:(js,javascript,Promise)