大体思路:
resolve方法实现异步的回调并得到结果通知,然后再通知onFulfilled
reject方法实现异步的回调并得到错误反馈,然后再通知onRejected

then方法实现对onFulfilled和onRejected的二次封装后,加载到回调队列_resolveQueue/_rejectQueue,等候通知,并且返回新的pomise实现链式调用

版本一

这个版本有个问题:当传给reject回调的参数是 promise 对象时,没做处理。

  1. // Promise/A+ 规范规定的三种状态
  2. const STATUS = {
  3. PENDING: 'pending',
  4. FULFILLED: 'fulfilled',
  5. REJECTED: 'rejected'
  6. }
  7. class MyPromise {
  8. // 构造函数接收一个执行回调
  9. constructor(executor) {
  10. this._status = STATUS.PENDING // Promise初始状态
  11. this._value = undefined // then回调的值
  12. this._resolveQueue = [] // resolve时触发的成功队列
  13. this._rejectQueue = [] // reject时触发的失败队列
  14. // 使用箭头函数固定this(resolve函数在executor中触发,不然找不到this)
  15. const resolve = value => {
  16. const run = () => {
  17. // Promise/A+ 规范规定的Promise状态只能从pending触发,变成fulfilled
  18. if (this._status === STATUS.PENDING) {
  19. this._status = STATUS.FULFILLED // 更改状态
  20. this._value = value // 储存当前值,用于then回调
  21. // 执行resolve回调
  22. while (this._resolveQueue.length) {
  23. const callback = this._resolveQueue.shift()
  24. callback(value)
  25. }
  26. }
  27. }
  28. //把resolve执行回调的操作封装成一个函数,放进setTimeout里,以实现promise异步调用的特性(规范上是微任务,这里是宏任务)
  29. setTimeout(run)
  30. }
  31. // 同 resolve
  32. const reject = value => {
  33. const run = () => {
  34. if (this._status === STATUS.PENDING) {
  35. this._status = STATUS.REJECTED
  36. this._value = value
  37. while (this._rejectQueue.length) {
  38. const callback = this._rejectQueue.shift()
  39. callback(value)
  40. }
  41. }
  42. }
  43. setTimeout(run)
  44. }
  45. // new Promise()时立即执行executor,并传入resolve和reject
  46. executor(resolve, reject)
  47. }
  48. // then方法,接收一个成功的回调和一个失败的回调
  49. then(onFulfilled, onRejected) {
  50. // 根据规范,如果then的参数不是function,则忽略它, 让值继续往下传递,链式调用继续往下执行
  51. typeof onFulfilled !== 'function' ? onFulfilled = value => value : null
  52. typeof onRejected !== 'function' ? onRejected = error => error : null
  53. // then 返回一个新的promise
  54. return new MyPromise((resolve, reject) => {
  55. const resolveFn = value => {
  56. try {
  57. const x = onFulfilled(value)
  58. // 分类讨论返回值,如果是Promise,那么等待Promise状态变更,否则直接resolve
  59. x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
  60. } catch (error) {
  61. reject(error)
  62. }
  63. }
  64. const rejectFn = error => {
  65. try {
  66. const x = onRejected(error)
  67. x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
  68. } catch (error) {
  69. reject(error)
  70. }
  71. }
  72. switch (this._status) {
  73. case STATUS.PENDING:
  74. this._resolveQueue.push(resolveFn)
  75. this._rejectQueue.push(rejectFn)
  76. break;
  77. case STATUS.FULFILLED:
  78. resolveFn(this._value)
  79. break;
  80. case STATUS.REJECTED:
  81. rejectFn(this._value)
  82. break;
  83. }
  84. })
  85. }
  86. catch(rejectFn) {
  87. return this.then(undefined, rejectFn)
  88. }
  89. finally(callback) {
  90. return this.then(value => MyPromise.resolve(callback()).then(() => value), error => {
  91. MyPromise.resolve(callback()).then(() => error)
  92. })
  93. }
  94. // 静态resolve方法
  95. static resolve(value) {
  96. return value instanceof MyPromise ? value : new MyPromise(resolve => resolve(value))
  97. }
  98. // 静态reject方法
  99. static reject(error) {
  100. return new MyPromise((resolve, reject) => reject(error))
  101. }
  102. // 静态all方法
  103. static all(promiseArr) {
  104. let count = 0
  105. let result = []
  106. return new MyPromise((resolve, reject) => {
  107. if (!promiseArr.length) {
  108. return resolve(result)
  109. }
  110. promiseArr.forEach((p, i) => {
  111. MyPromise.resolve(p).then(value => {
  112. count++
  113. result[i] = value
  114. if (count === promiseArr.length) {
  115. resolve(result)
  116. }
  117. }, error => {
  118. reject(error)
  119. })
  120. })
  121. })
  122. }
  123. // 静态race方法
  124. static race(promiseArr) {
  125. return new MyPromise((resolve, reject) => {
  126. promiseArr.forEach(p => {
  127. MyPromise.resolve(p).then(value => {
  128. resolve(value)
  129. }, error => {
  130. reject(error)
  131. })
  132. })
  133. })
  134. }
  135. }

版本二

  1. // 判断变量否为function
  2. const isFunction = variable => typeof variable === 'function'
  3. // 定义Promise的三种状态常量
  4. const PENDING = 'PENDING'
  5. const FULFILLED = 'FULFILLED'
  6. const REJECTED = 'REJECTED'
  7. class MyPromise {
  8. constructor (handle) {
  9. if (!isFunction(handle)) {
  10. throw new Error('MyPromise must accept a function as a parameter')
  11. }
  12. // 添加状态
  13. this._status = PENDING
  14. // 添加状态
  15. this._value = undefined
  16. // 添加成功回调函数队列
  17. this._fulfilledQueues = []
  18. // 添加失败回调函数队列
  19. this._rejectedQueues = []
  20. // 执行handle
  21. try {
  22. handle(this._resolve.bind(this), this._reject.bind(this))
  23. } catch (err) {
  24. this._reject(err)
  25. }
  26. }
  27. // 添加resovle时执行的函数
  28. _resolve (val) {
  29. const run = () => {
  30. if (this._status !== PENDING) return
  31. // 依次执行成功队列中的函数,并清空队列
  32. const runFulfilled = (value) => {
  33. let cb;
  34. while (cb = this._fulfilledQueues.shift()) {
  35. cb(value)
  36. }
  37. }
  38. // 依次执行失败队列中的函数,并清空队列
  39. const runRejected = (error) => {
  40. let cb;
  41. while (cb = this._rejectedQueues.shift()) {
  42. cb(error)
  43. }
  44. }
  45. /* 如果resolve的参数为Promise对象,则必须等待该Promise对象状态改变后,
  46. 当前Promsie的状态才会改变,且状态取决于参数Promsie对象的状态
  47. */
  48. if (val instanceof MyPromise) {
  49. val.then(value => {
  50. this._value = value
  51. this._status = FULFILLED
  52. runFulfilled(value)
  53. }, err => {
  54. this._value = err
  55. this._status = REJECTED
  56. runRejected(err)
  57. })
  58. } else {
  59. this._value = val
  60. this._status = FULFILLED
  61. runFulfilled(val)
  62. }
  63. }
  64. // 为了支持同步的Promise,这里采用异步调用
  65. setTimeout(run, 0)
  66. }
  67. // 添加reject时执行的函数
  68. _reject (err) {
  69. if (this._status !== PENDING) return
  70. // 依次执行失败队列中的函数,并清空队列
  71. const run = () => {
  72. this._status = REJECTED
  73. this._value = err
  74. let cb;
  75. while (cb = this._rejectedQueues.shift()) {
  76. cb(err)
  77. }
  78. }
  79. // 为了支持同步的Promise,这里采用异步调用
  80. setTimeout(run, 0)
  81. }
  82. // 添加then方法
  83. then (onFulfilled, onRejected) {
  84. const { _value, _status } = this
  85. // 返回一个新的Promise对象
  86. return new MyPromise((onFulfilledNext, onRejectedNext) => {
  87. // 封装一个成功时执行的函数
  88. let fulfilled = value => {
  89. try {
  90. if (!isFunction(onFulfilled)) {
  91. onFulfilledNext(value)
  92. } else {
  93. let res = onFulfilled(value);
  94. if (res instanceof MyPromise) {
  95. // 如果当前回调函数返回MyPromise对象,必须等待其状态改变后在执行下一个回调
  96. res.then(onFulfilledNext, onRejectedNext)
  97. } else {
  98. //否则会将返回结果直接作为参数,传入下一个then的回调函数,并立即执行下一个then的回调函数
  99. onFulfilledNext(res)
  100. }
  101. }
  102. } catch (err) {
  103. // 如果函数执行出错,新的Promise对象的状态为失败
  104. onRejectedNext(err)
  105. }
  106. }
  107. // 封装一个失败时执行的函数
  108. let rejected = error => {
  109. try {
  110. if (!isFunction(onRejected)) {
  111. onRejectedNext(error)
  112. } else {
  113. let res = onRejected(error);
  114. if (res instanceof MyPromise) {
  115. // 如果当前回调函数返回MyPromise对象,必须等待其状态改变后在执行下一个回调
  116. res.then(onFulfilledNext, onRejectedNext)
  117. } else {
  118. //否则会将返回结果直接作为参数,传入下一个then的回调函数,并立即执行下一个then的回调函数
  119. onFulfilledNext(res)
  120. }
  121. }
  122. } catch (err) {
  123. // 如果函数执行出错,新的Promise对象的状态为失败
  124. onRejectedNext(err)
  125. }
  126. }
  127. switch (_status) {
  128. // 当状态为pending时,将then方法回调函数加入执行队列等待执行
  129. case PENDING:
  130. this._fulfilledQueues.push(fulfilled)
  131. this._rejectedQueues.push(rejected)
  132. break
  133. // 当状态已经改变时,立即执行对应的回调函数
  134. case FULFILLED:
  135. fulfilled(_value)
  136. break
  137. case REJECTED:
  138. rejected(_value)
  139. break
  140. }
  141. })
  142. }
  143. // 添加catch方法
  144. catch (onRejected) {
  145. return this.then(undefined, onRejected)
  146. }
  147. // 添加静态resolve方法
  148. static resolve (value) {
  149. // 如果参数是MyPromise实例,直接返回这个实例
  150. if (value instanceof MyPromise) return value
  151. return new MyPromise(resolve => resolve(value))
  152. }
  153. // 添加静态reject方法
  154. static reject (value) {
  155. return new MyPromise((resolve ,reject) => reject(value))
  156. }
  157. // 添加静态all方法
  158. static all (list) {
  159. return new MyPromise((resolve, reject) => {
  160. /**
  161. * 返回值的集合
  162. */
  163. let values = []
  164. let count = 0
  165. for (let [i, p] of list.entries()) {
  166. // 数组参数如果不是MyPromise实例,先调用MyPromise.resolve
  167. this.resolve(p).then(res => {
  168. values[i] = res
  169. count++
  170. // 所有状态都变成fulfilled时返回的MyPromise状态就变成fulfilled
  171. if (count === list.length) resolve(values)
  172. }, err => {
  173. // 有一个被rejected时返回的MyPromise状态就变成rejected
  174. reject(err)
  175. })
  176. }
  177. })
  178. }
  179. // 添加静态race方法
  180. static race (list) {
  181. return new MyPromise((resolve, reject) => {
  182. for (let p of list) {
  183. // 只要有一个实例率先改变状态,新的MyPromise的状态就跟着改变
  184. this.resolve(p).then(res => {
  185. resolve(res)
  186. }, err => {
  187. reject(err)
  188. })
  189. }
  190. })
  191. }
  192. finally (cb) {
  193. return this.then(
  194. value => MyPromise.resolve(cb()).then(() => value),
  195. reason => MyPromise.resolve(cb()).then(() => { throw reason })
  196. );
  197. }
  198. }

版本三

const isFunc = obj => Object.prototype.toString.call(obj) === '[object Function]';
const isObj = obj => Object.prototype.toString.call(obj) === '[object Object]';
// 等待态 规范 2.1.1
const PENDING = 'pending';
// 执行态 规范 2.1.2
const FULFILLED = 'fulfilled';
// 拒绝态 规范 2.1.3
const REJECTED = 'rejected';

class MyPromise {
  constructor(fn) {
    this.status = PENDING;
    this.value = undefined;
    this.filfulledQueues = [];
    this.rejectedQueues = [];
    try {
      fn(this._resolve.bind(this), this._reject.bind(this));
    } catch (err) {
      this._reject(err);
    }
  }
  //传入 promise 的第一个参数 resolve
  _resolve(val) {
    if (val instanceof MyPromise) {
      val.then(this._resolve, this._reject);
    } else if (isObj(val) || isFunc(val)) {
      try {
        if (isFunc(val.then)) {
          val.then(this._resolve, this._reject);
        }
      } catch (e) {
        this._reject(e);
      }
    }
    this._execCallback(FULFILLED, this.filfulledQueues, val);
  }
  //传入 promise 的第二个参数 reject
  _reject(val) {
    this._execCallback(REJECTED, this.rejectedQueues, val);
  }
  _execCallback(status, list, val) {
    //规范 2.2.4 onFulfilled 和 onRejected 只有在执行环境堆栈仅包含平台代码时才可被调用,且被作为函数调用(即没有 this 值)
    setTimeout(() => {
      if (this.status !== PENDING) {
        return;
      }
      this.status = status;
      this.value = val;
      let cb;
      //规范 2.2.6
      while ((cb = list.shift())) {
        cb(val);
      }
    });
  }
  //规范 2.3 Promise 解决过程 [[Resolve]](promise, x)
  _resolvePromise(newPromise, x, resolve, reject) {
    if (newPromise === x) {
      //规范 2.3.1
      return reject(new TypeError('循环引用'));
    }
    if (x instanceof MyPromise) {
      //规范 2.3.2
      x.then(resolve, reject);
    } else if (isObj(x) || isFunc(x)) {
      //规范 2.3.3
      try {
        //规范 2.3.3.3
        if (isFunc(x.then)) {
          x.then(resolve, reject);
        } else {
          //规范 2.3.3.4
          resolve(x);
        }
      } catch (e) {
        //规范 2.3.3.3.4
        reject(e);
      }
    } else {
      //规范 2.3.4
      resolve(x);
    }
  }
  //规范 2.2
  then(onFulfilled, onRejected) {
    let newPromise;
    //规范 2.2.1,2.2.7.3
    onFulfilled = isFunc(onFulfilled) ? onFulfilled : val => val;
    //规范 2.2.1,2.2.7.4
    onRejected = isFunc(onRejected)
      ? onRejected
      : err => {
          throw err;
        };
    //规范 2.2.7 then 方法必须返回一个 promise 对象:promise2 = promise1.then(onFulfilled, onRejected);
    return (newPromise = new MyPromise((onFulfilledNext, onRejectedNext) => {
      // onFulfilledNext, onRejectedNext 即该 then 的下一个 then 里传的 resolve 和 reject
      if (this.status === FULFILLED || this.status === REJECTED) {
        //规范 2.2.4 onFulfilled 和 onRejected 只有在执行环境堆栈仅包含平台代码时才可被调用
        setTimeout(() => {
          // 规范 2.2.7.1 不论 promise1 被 reject 还是被 resolve 时 promise2 都会被 resolve(走_resolvePromise方法),只有出现异常时才会被 rejected。
          try {
            //规范 2.2.2,2.2.3,2.2.5
            const x = this.status === FULFILLED ? onFulfilled(this.value) : onRejected(this.value);
            this._resolvePromise(newPromise, x, onFulfilledNext, onRejectedNext);
          } catch (e) {
            //规范 2.2.7.2  这里如果x为捕获的err(即 onRejected 不是函数 2.2.7.4)也会进入
            onRejectedNext(e);
          }
        });
      } else if (this.status === PENDING) {
        //规范 2.2.6.1
        this.filfulledQueues.push(() => {
          try {
            //规范 2.2.2,2.2.5
            const x = onFulfilled(this.value);
            this._resolvePromise(newPromise, x, onFulfilledNext, onRejectedNext);
          } catch (e) {
            //规范 2.2.7.2
            onRejectedNext(e);
          }
        });
        //规范 2.2.6.2
        this.rejectedQueues.push(() => {
          try {
            //规范 2.2.3,2.2.5
            const x = onRejected(this.value);
            this._resolvePromise(newPromise, x, onFulfilledNext, onRejectedNext);
          } catch (e) {
            //规范 2.2.7.2
            onRejectedNext(e);
          }
        });
      }
    }));
  }
  //catch 方法
  catch(onRejected) {
    return this.then(null, onRejected);
  }
  //finally 方法
  finally(cb) {
    return this.then(
      val => {
        MyPromise.resolve(cb()).then(() => val);
      },
      err => {
        MyPromise.resolve(cb()).then(() => {
          throw err;
        });
      }
    );
  }
  //resolve 方法
  static resolve(params) {
    return new MyPromise(resolve => {
      resolve(params);
    });
  }
  //reject 方法
  static reject(err) {
    return new MyPromise((resolve, reject) => {
      reject(err);
    });
  }
  //all 方法
  static all(params) {
    let count = 0;
    let valueList = [];
    const promises = Array.from(params);
    return new MyPromise((resolve, reject) => {
      promises.forEach((item, index) => {
        if (!item instanceof MyPromise) {
          item = MyPromise.resolve(item);
        }
        item.then(r => {
          valueList[index] = r;
          if (promises.length === ++count) {
            resolve(valueList);
          }
        }, reject);
      });
    });
  }
  //race 方法
  static race(params) {
    const promises = Array.from(params);
    return new MyPromise((resolve, reject) => {
      promises.forEach(item => {
        if (!item instanceof MyPromise) {
          item = MyPromise.resolve(item);
        }
        item.then(resolve, reject);
      });
    });
  }
}

参考

Promise系列2——Promises_A+ 规范解读
https://promisesaplus.com/
看了就会,手写Promise原理,最通俗易懂的版本!!!
promise规范实现
Promise知识汇总和面试情况