«
Promise的实现

时间:2022-4   


function myPromise(constructor){ let self=this;
  self.status="pending" //定义状态改变前的初始状态 
  self.value=undefined;//定义状态为resolved的时候的状态 
  self.reason=undefined;//定义状态为rejected的时候的状态 
  function resolve(value){
    //两个==="pending",保证了了状态的改变是不不可逆的 
    if(self.status==="pending"){
      self.value=value;
      self.status="resolved"; 
    }
  }
  function reject(reason){
     //两个==="pending",保证了了状态的改变是不不可逆的
     if(self.status==="pending"){
        self.reason=reason;
        self.status="rejected"; 
      }
  }
  //捕获构造异常 
  try{
      constructor(resolve,reject);
  }catch(e){
    reject(e);
    } 
}
myPromise.prototype.then=function(onFullfilled,onRejected){ 
  let self=this;
  switch(self.status){
    case "resolved": onFullfilled(self.value); break;
    case "rejected": onRejected(self.reason); break;
    default: 
  }
}

// 测试
var p=new myPromise(function(resolve,reject){resolve(1)}); 
p.then(function(x){console.log(x)})
//输出1

6)大厂专供版

const PENDING = "pending"; 
const FULFILLED = "fulfilled"; 
const REJECTED = "rejected";
const resolvePromise = (promise, x, resolve, reject) => {
  if (x === promise) {
    // If promise and x refer to the same object, reject promise with a TypeError as the reason.
    reject(new TypeError('循环引用'))
  }
  // if x is an object or function,
  if (x !== null && typeof x === 'object' || typeof x === 'function') {
    // If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.
    let called
    try { // If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.
      let then = x.then // Let then be x.then
      // If then is a function, call it with x as this
      if (typeof then === 'function') {
        // If/when resolvePromise is called with a value y, run [[Resolve]](promise, y)
        // If/when rejectPromise is called with a reason r, reject promise with r.
        then.call(x, y => {
          if (called) return
          called = true
          resolvePromise(promise, y, resolve, reject)
        }, r => {
          if (called) return
          called = true
          reject(r)
        })
      } else {
        // If then is not a function, fulfill promise with x.
        resolve(x)
      }
    } catch (e) {
      if (called) return
      called = true
      reject(e)
    }
  } else {
    // If x is not an object or function, fulfill promise with x
    resolve(x)
  }
}
function Promise(excutor) {
  let that = this; // 缓存当前promise实例例对象
  that.status = PENDING; // 初始状态
  that.value = undefined; // fulfilled状态时 返回的信息
  that.reason = undefined; // rejected状态时 拒绝的原因 
  that.onFulfilledCallbacks = []; // 存储fulfilled状态对应的onFulfilled函数
  that.onRejectedCallbacks = []; // 存储rejected状态对应的onRejected函数
  function resolve(value) { // value成功态时接收的终值
    if(value instanceof Promise) {
      return value.then(resolve, reject);
    }
    // 实践中要确保 onFulfilled 和 onRejected ⽅方法异步执⾏行行,且应该在 then ⽅方法被调⽤用的那⼀一轮事件循环之后的新执⾏行行栈中执⾏行行。
    setTimeout(() => {
      // 调⽤用resolve 回调对应onFulfilled函数
      if (that.status === PENDING) {
        // 只能由pending状态 => fulfilled状态 (避免调⽤用多次resolve reject)
        that.status = FULFILLED;
        that.value = value;
        that.onFulfilledCallbacks.forEach(cb => cb(that.value));
      }
    });
  }
  function reject(reason) { // reason失败态时接收的拒因
    setTimeout(() => {
      // 调⽤用reject 回调对应onRejected函数
      if (that.status === PENDING) {
        // 只能由pending状态 => rejected状态 (避免调⽤用多次resolve reject)
        that.status = REJECTED;
        that.reason = reason;
        that.onRejectedCallbacks.forEach(cb => cb(that.reason));
      }
    });
  }

  // 捕获在excutor执⾏行行器器中抛出的异常
  // new Promise((resolve, reject) => {
  //     throw new Error('error in excutor')
  // })
  try {
    excutor(resolve, reject);
  } catch (e) {
    reject(e);
  }
}
Promise.prototype.then = function(onFulfilled, onRejected) {
  const that = this;
  let newPromise;
  // 处理理参数默认值 保证参数后续能够继续执⾏行行
  onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
  onRejected = typeof onRejected === "function" ? onRejected : reason => {
    throw reason;
  };
  if (that.status === FULFILLED) { // 成功态
    return newPromise = new Promise((resolve, reject) => {
      setTimeout(() => {
        try{
          let x = onFulfilled(that.value);
          resolvePromise(newPromise, x, resolve, reject); //新的promise resolve 上⼀一个onFulfilled的返回值
        } catch(e) {
          reject(e); // 捕获前⾯面onFulfilled中抛出的异常then(onFulfilled, onRejected);
        }
      });
    })
  }
  if (that.status === REJECTED) { // 失败态
    return newPromise = new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          let x = onRejected(that.reason);
          resolvePromise(newPromise, x, resolve, reject);
        } catch(e) {
          reject(e);
        }
      });
    });
  }
  if (that.status === PENDING) { // 等待态
// 当异步调⽤用resolve/rejected时 将onFulfilled/onRejected收集暂存到集合中
    return newPromise = new Promise((resolve, reject) => {
      that.onFulfilledCallbacks.push((value) => {
        try {
          let x = onFulfilled(value);
          resolvePromise(newPromise, x, resolve, reject);
        } catch(e) {
          reject(e);
        }
      });
      that.onRejectedCallbacks.push((reason) => {
        try {
          let x = onRejected(reason);
          resolvePromise(newPromise, x, resolve, reject);
        } catch(e) {
          reject(e);
        }
      });
    });
  }
};
/**
 * 抽象表达
 * Promise是 js 进行异步编辑的新的解决方案(旧的方式:纯回调的形式)
 * 具体表达
 * 1 从语法上来说Promise 是一个构造函数
 * 2 从功能上来说promise 对象用来封装一个异步操作并可以获取其结果
 * 状态改变
 * pending 变为 resolved
 * pending rejected
 * 一个promise 对象只能改变一次
 * 无论变为成功还是失败,都会有一个结果数据
 * 成功的结果数据一般称为value 失败的结果数据一般称为reason
 * 为什么要使用promise
 *
 * 1 指定的回调函数的方式更加灵活
 * 旧:必须要启动异步任务前指定
 * promise 启动异步任务=>返回 promise对象=>给promise对象
 * 绑定回调函数(甚至可以在异步结束后指定/多个)
 *
 * 2 promise 支持链式调用。可以解决回调地狱问题
 * 什么是回调地狱 回调函数嵌套调用,外部回调函异步执行的结果是嵌套的
 * 回调函数执行条件
 * 回调地狱的缺点?不便于阅读/不便于异常处理
 * 解决方案 promise 链式调用
 * 错误回调:异常传透
 * then 是原型对象方法
 * new Promise 是实例对象方法
 * Promise.all promise函数对象方法
 *
* */
(function (window) {
  /**
   * Promise 构造函数
   * excutor 执行器函数 同步执行
   * */
  const PENDING='pending'
  const RESOLVED='resolved'
  const REJECTED='rejected'
  function Promise(excutor) {
      const self = this
      self.status = 'pending'// 给promise 对象指定status 属性,初始值为pending
      self.data = undefined// 给promise 对象指定一个用一存储结果数据的属性
      self.callbacks=[]// 每个元素的结构{onResolve(){},onRejected(){}}
      // 立即同步执行excutor
      function resolve(value) {
          if(self.status !==PENDING) return
          //将状态改为resolve
          self.status= RESOLVED
          //保存value数据
          self.data = value
          //如果有待执行callback函数,立即异步执行回调 onResolved
          if(self.callbacks.length>0){
              setTimeout(()=>{//放入队列中执行所有成功的回调
                  self.callbacks.forEach((callbacksObj)=>{
                      callbacksObj.onResolved(value)
                  })
              })
          }
      }
      function reject(reason) {
          if(self.status !==PENDING) return
          //将状态改为rejected
          self.status= REJECTED
          //保存value数据
          self.data = reason
          //如果有待执行callback函数,立即异步执行回调onRejected
          if(self.callbacks.length>0){
              setTimeout(()=>{//放入队列中执行所有成功的回调
                  self.callbacks.forEach((callbacksObj)=>{
                      callbacksObj.onRejected(reason)
                  })
              })
          }
      }
      try{
          excutor(resolve,reject)
      }catch (error) {// 如果执行器抛出异常将失败
         reject(error)
      }

  }

  /**
   *  Promise原型对象then方法
   *  成功或失败的回调函数
   *  返回一个新的promise对象
   * */
  Promise.prototype.then = function (onResolved, onRejected) {
      const self = this
      // 返回一个新地promise对象
      return new Promise((resolve,reject)=>{
          if(self.status===PENDING){
              this.callbacks.push({
                  onResolved,
                  onRejected
              })
          }else if(self.status === RESOLVED){
              setTimeout(()=>{
                  /**
                   * 结果异常 return 的promise 就会失败 reason 就是error
                   * 执行返回非 promise
                   * */
                  try{
                      const result =  onResolved(self.data)
                      if(result instanceof Promise){
                          result.then(
                              value=> resolve(value),
                              reason=> reject(reason)
                          )
                      }else{
                          resolve(result)
                      }
                  }catch (error) {
                      reject(error)
                  }

              })
          }else{
              // rejected
              setTimeout(()=>{
                  onRejected(self.data)
              })
          }
      })

  }
  //向外暴露promise函数
  window.Promise = Promise
})(window)