MyPromise.js

  1. // 定义常量是为了复用且代码有提示
  2. const PENDING = 'pending' // 等待
  3. const FULFILLED = 'fulfilled' // 成功
  4. const REJECTED = 'rejected' // 失败
  5. // 定义一个构造函数
  6. class MyPromise {
  7. constructor(exector){
  8. // 捕获执行器的错误
  9. try {
  10. // exector是一个执行器,立即执行,并传入resolve和reject方法
  11. exector(this.resolve, this.reject)
  12. } catch (error) {
  13. this.reject(error)
  14. }
  15. }
  16. // 初始状态
  17. status = PENDING
  18. // 成功的值
  19. value = undefined
  20. // 失败的理由
  21. reason = undefined
  22. // 定义成功回调参数
  23. successCallback = []
  24. // 定义失败回调参数
  25. failCallback = []
  26. // 定义数组的原因
  27. // .then方法可以被多次调用, 每次存储的内容要互不影响
  28. // 普通函数this指向的是window或者undefined
  29. // 用箭头函数就可以让this指向当前实例对象
  30. resolve = value => {
  31. // 判断状态是不是等待,阻止向下执行
  32. if (this.status !== PENDING) return;
  33. // 设置状态为成功
  34. this.status = FULFILLED
  35. // 保存成功的值
  36. this.value = value
  37. // 成功回调存在就调用
  38. // this.successCallback&&this.successCallback(value)
  39. // 为了then的多次调用,回调参数保存要求互不影响改进
  40. // shift方法是在数组中删除值,返回被删除的项,每执行一个就删除一个,最终变为0
  41. while(this.successCallback.length) this.successCallback.shift()()
  42. }
  43. reject = reason => {
  44. // 判断状态是不是等待,阻止向下执行
  45. if (this.status !== PENDING) return;
  46. // 设置状态为失败
  47. this.status = REJECTED
  48. // 保存失败的值
  49. this.reason = reason
  50. // 失败回调存在就调用
  51. // this.failCallback&&this.failCallback(reason)
  52. // 为了then的多次调用,回调参数保存要求互不影响改进
  53. // shift方法是在数组中删除值,返回被删除的项,每执行一个就删除一个,最终变为0
  54. while(this.failCallback.length) this.failCallback.shift()()
  55. }
  56. then(successCallback, failCallback) {
  57. // 将then参数变成可选参数
  58. successCallback = successCallback ? successCallback : value => value;
  59. failCallback = failCallback ? failCallback : reason => { throw reason }
  60. // 为了实现then的链式调用, 需要返回一个promise对象
  61. let promise2 = new MyPromise((resolve, reject) => {
  62. // 判断状态
  63. if (this.status === FULFILLED) {
  64. // successcallback(this.value)
  65. // 使用setTimeout把代码变成异步代码,才能拿到promise2, 去处理then返回自身对象嵌套的问题.
  66. setTimeout(() => {
  67. // 捕获成功回调方法的错误
  68. try {
  69. // 成功调用成功回调,并把值返回
  70. let x = successCallback(this.value)
  71. // 把返回值传递给下一个then方法
  72. resolvePromise(promise2, x, resolve, reject)
  73. } catch (error) {
  74. reject(error)
  75. }
  76. }, 0)
  77. } else if (this.status === REJECTED) {
  78. // 失败调用失败回调,并把原因返回
  79. // failCallback(this.reason)
  80. setTimeout(() => {
  81. // 捕获成功回调方法的错误
  82. try {
  83. // 成功调用成功回调,并把值返回
  84. let x = failCallback(this.reason)
  85. // 把返回值传递给下一个then方法
  86. resolvePromise(promise2, x, resolve, reject)
  87. } catch (error) {
  88. reject(error)
  89. }
  90. }, 0)
  91. } else {
  92. // 等待状态中
  93. // 不知道成功还是失败,所以先把回调参数存起来, 等状态确定再调用
  94. this.successCallback.push(() => {
  95. setTimeout(() => {
  96. try {
  97. let x = successCallback(this.value)
  98. resolvePromise(promise2, x, resolve, reject)
  99. } catch (error) {
  100. reject(error)
  101. }
  102. }, 0)
  103. })
  104. this.failCallback.push(() => {
  105. setTimeout(() => {
  106. try {
  107. let x = failCallback(this.reason)
  108. resolvePromise(promise2, x, resolve, reject)
  109. } catch (error) {
  110. reject(error)
  111. }
  112. }, 0)
  113. });
  114. }
  115. })
  116. return promise2
  117. }
  118. finally(callback) {
  119. return this.then(value => {
  120. // callback();
  121. // return value
  122. // 利用resolve的等待异步完成功能, 实现finally的return异步等待功能
  123. return MyPromise.resolve(callback()).then(() => value)
  124. }, reason => {
  125. // callback()
  126. // throw reason
  127. return MyPromise.resolve(callback()).then(() => { throw reason })
  128. })
  129. }
  130. catch(failCallback) {
  131. return this.then(undefined, failCallback)
  132. }
  133. static all(array) {
  134. let result = [];
  135. let index = 0;
  136. return new MyPromise((resolve, reject) => {
  137. function addData(key, value) {
  138. result[key] = value
  139. index++;
  140. if (index === array.length) {
  141. resolve(result)
  142. }
  143. }
  144. for(let i = 0; i < array.length; i++) {
  145. let current = array[i]
  146. if (current instanceof MyPromise) {
  147. current.then(value => addData(i, array[i]), reason => reject(reason))
  148. } else {
  149. addData(i, array[i])
  150. }
  151. }
  152. })
  153. }
  154. static resolve(value) {
  155. if (value instanceof MyPromise) return value
  156. return new MyPromise(resolve => resolve(value))
  157. }
  158. }
  159. // 返回普通值和promise对象处理
  160. // 普通值 => 直接传递给下一个then
  161. // promise对象 先判断promise的返回值
  162. // value => resolve reason => reject
  163. function resolvePromise(promise2, x, resolve, reject) {
  164. // 判断then方法返回的是不是自己的promise, 是则会产生循环嵌套, 阻止程序运行, 报错
  165. if (promise2 === x) {
  166. return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
  167. }
  168. if (x instanceof MyPromise) {
  169. // promise对象
  170. // x.then(value => resolve(value), reason => reject(reason))
  171. x.then(resolve, reject)
  172. } else {
  173. // 普通值
  174. resolve(x)
  175. }
  176. }
  177. module.exports = MyPromise