coverPiccoverPic

实现一个 Promise A+ 规范的 Promise

简介 Promise A+ 规范

变量和术语

  1. Promise 具有 3 种状态:pending、fulfilled、rejected,初始状态为 pending,切换为 fulfilled 或者 rejected 后就不能再转换。
ts
  1. const testPromise = new Promise((resolve, reject) => {
  2. // DO SOMETHING
  3. })
  • 像这样子,传入的函数我们称为executorresolvereject会触发 Promise 的状态以及数据更新。

  • Promise A+ 规范的 Promise 上的方法只有简单的thencatchfinally什么的都没有。

  • 从 Promise A+ 的测试用例(写在后面噢)来看,可以使用testPromise.resolvetestPromise.reject在实例化Promise之后手动修改它的状态和数据。

关于 then 方法

  1. then方法具有onFulfilledonRejected两个入参,返回一个 Promise(链式调用)。
ts
  1. const temp = testPromise.then(function onFulfilled (value) {
  2. // DO SOMETHING
  3. }, function onRejected (reason) {
  4. // DO SOMETHING
  5. })
  6. console.log(temp instanceof Promise) // true
  7. console.log(temp === testPromise) // false
  • Promise 从 pending 状态切换到 fulfilled 或者 rejected 时,执行此前then传入的onFulfilledonRejected。fulfilled 状态的 Promise 会执行then传入的onFulfilled,rejected 状态的 Promise 会执行then传入的onRejected

  • 执行onFulfilledonRejected的结果会被传入新的 Promise tempresolve方法中,如果发生了错误则传入reject中,改变的状态和数据。

  • onFulfilled或者onRejected不是函数时,返回的 Promise 与原 Promise 具有相同的状态和数据(传值穿透)。

  • 不支持我返回我自己,onFulfilled或者onRejected返回该then返回的 Promise 时,抛出TypeError错误,例如:

ts
  1. const temp = testPromise.then(function onFulfilled (value) {
  2. return temp
  3. })

关于兼容 thenable 对象

  1. thenable 的对象是具有then方法的对象或者函数(typeof返回object或者function)。then方法接受两个回调函数onResolvePromiseonRejectPromise,类似于这里的 Promise 的then。thenable 实际上包括实现了 Promise A+ 规范的 Promise,例如 ES6 原生的 Promise。举个栗子:
ts
  1. const thenable = {
  2. then: function (onResolvePromise) {
  3. onResolvePromise('miao~~')
  4. }
  5. }
  • 如果触发了onFulfilled,返回了一个 thenable。如果是该 Promise 的实例,不是当前 Promise,则传入onFulfilledonRejected,调用 then 方法。

  • 兼容其他 thenable 要求onFulfilled的回调可以给 thenable 的then方法传入两个回调函数,像该 Promise 一样解析。

  • 在解析 thenable 对象时(也就是onResolvePromise或者onRejectPromise都没有被触发),新的onFulfilled或者onRejected触发将被忽略。此时,当前 Promise 是处于 pending 状态的,如果触发转向其他两个状态的改变也会被忽略(这一点主要是在测试用例中体现出来,看标准没怎么注意到)。

  • 允许其他 thenable 对象乱写,这里需要处理 thenable 对象重复触发onResolvePromise或/和onRejectPromise的情况,这两个回调函数最多只能被调用各 1 次。

  1. resolvereject被触发时发生什么事了?此时 Promise 的状态仍未真正变化,会进入一段处理程序,规范称之为 Promise Resolution Procedure,主要逻辑是如果传入的是非 thenable 对象或者基本类型则直接修改 Promise 的状态和数据,是 thenable 就执行上述 thenable 相关逻辑。

  2. 其他详细见 Promise A+ 规范。

简单地写一个 Promise

ts
  1. enum PromiseState {
  2. fulfilled = 'fulfilled',
  3. pending = 'pending',
  4. rejected = 'rejected'
  5. }
  6. type PromiseData = any
  7. type ThenCallback = any
  8. class ShikaPromise {
  9. data: PromiseData = undefined
  10. state: PromiseState = PromiseState.pending
  11. constructor (executor: Function) {
  12. // 如果报错了,Promise 处于 rejected 状态
  13. try {
  14. executor(this.resolve, this.reject)
  15. } catch(error) {
  16. this.reject(error)
  17. }
  18. }
  19. resolve (value: PromiseData) {
  20. if (this.state === PromiseState.pending) {
  21. this.state = PromiseState.fulfilled
  22. this.data = value
  23. }
  24. }
  25. reject (reason: PromiseData) {
  26. if (this.state === PromiseState.pending) {
  27. this.state = PromiseState.rejected
  28. this.data = reason
  29. }
  30. }
  31. then (onFulfilled: ThenCallback, onRejected: ThenCallback) {
  32. // TODO
  33. }
  34. }

下面就来写then方法实现异步的链式调用。

then 方法

then返回一个 Promise,虽然 Promise A+ 规范没有说明需要返回的 Promise 不能和原有的是同一个,但是考虑到后续链式调用也会涉及到 Promise 状态的改变,所以这里就返回一个新的 Promise。

假设const promise2 = promise1.then(onFulfilled, onRejected),调用promise1.then时创建一个新的 Promise promise2返回出去。用过 ES6 的Promise很好理解,如果原有promise1是 fulfilled 的,则在新的promise2executor中的resolve传入onFulfilled的结果,如果promise1处于失败状态,rejected 了,则在promise2resolve中传入onResolve的结果。

fulfilled 和 rejected 状态

ts
  1. // ...
  2. class ShikaPromise {
  3. // ...
  4. private processFinish (
  5. resolve: Function,
  6. reject: Function,
  7. onFulfilledCallback: Function
  8. ) {
  9. process.nextTick(() => {
  10. try {
  11. const x = onFulfilledCallback(this.data)
  12. resolve(x)
  13. } catch (error) {
  14. reject(error)
  15. }
  16. })
  17. }
  18. then (onFulfilled?: ThenCallback, onRejected?: ThenCallback) {
  19. switch (this.state) {
  20. case PromiseState.fulfilled: {
  21. return new ShikaPromise((resolve: Function, reject: Function) => {
  22. this.processFinish(
  23. resolve,
  24. reject,
  25. onFulfilledCallback
  26. )
  27. })
  28. }
  29. case PromiseState.rejected: {
  30. return new ShikaPromise((resolve: Function, reject: Function) => {
  31. this.processFinish(
  32. resolve,
  33. reject,
  34. onRejectedCallback
  35. )
  36. })
  37. }
  38. default: {
  39. // TODO
  40. }
  41. }
  42. }

pending 状态

promise1在等待的时候,可以在promise1上新建两个属性onResolvedCallbackonRejectedCallback缓存给promise2触发resolvereject的回调函数。promise2处于 pending 状态,promise1切换状态后触发这些回调函数,用来改变promise2的状态。

ts
  1. // ...
  2. class ShikaPromise {
  3. // 记录 fulfilled 或者 rejected 后执行的回调函数,将会用于修改 then 方法返回的 Promise 的 data
  4. private onResolvedCallback: Function[] = []
  5. private onRejectedCallback: Function[] = []
  6. // ...
  7. resolve (value: PromiseData) {
  8. if (this.state === PromiseState.pending) {
  9. this.state = PromiseState.fulfilled
  10. this.data = value
  11. // 执行所有传入的回调函数
  12. const len = this.onResolvedCallback.length
  13. for (let i = 0; i < len; i++) {
  14. this.onResolvedCallback[i](value)
  15. }
  16. }
  17. }
  18. reject (reason: PromiseData) {
  19. if (this.state === PromiseState.pending) {
  20. this.state = PromiseState.rejected
  21. this.data = reason
  22. // 执行所有传入的回调函数
  23. const len = this.onRejectedCallback.length
  24. for (let i = 0; i < len; i++) {
  25. this.onRejectedCallback[i](reason)
  26. }
  27. }
  28. }
  29. // ...
  30. then (onFulfilled?: ThenCallback, onRejected?: ThenCallback) {
  31. switch (this.state) {
  32. case PromiseState.fulfilled: {
  33. // ...
  34. }
  35. case PromiseState.rejected: {
  36. // ...
  37. }
  38. default: {
  39. return new ShikaPromise((resolve: Function, reject: Function) => {
  40. this.onResolvedCallback.push(() => {
  41. this.processFinish(
  42. resolve,
  43. reject,
  44. onFulfilledCallback
  45. )
  46. })
  47. this.onRejectedCallback.push(() => {
  48. this.processFinish(
  49. resolve,
  50. reject,
  51. onRejectedCallback
  52. )
  53. })
  54. })
  55. }
  56. }
  57. }
  58. }

如何处理 Promise Resolution Procedure

resolve 和 reject 包含 Promise Resolution Procedure 逻辑

上面说到,resolvereject会进入 Promise Resolution Procedure 逻辑,这里先把resolvereject改造一下:

ts
  1. // ...
  2. class ShikaPromise {
  3. // ...
  4. private resolveData (
  5. resolve: Function,
  6. reject: Function,
  7. data: PromiseData,
  8. // 因为 resolve 卡住时 Promise 状态是不能改变的,因此把 reject 情况也统一处理
  9. targetState: PromiseState.fulfilled | PromiseState.rejected
  10. ) {
  11. // TODO
  12. }
  13. resolve (value: PromiseData) {
  14. this.resolveData(
  15. this.processResolve.bind(this),
  16. this.processReject.bind(this),
  17. value,
  18. PromiseState.fulfilled
  19. )
  20. }
  21. reject (reason: PromiseData) {
  22. this.resolveData(
  23. this.processResolve.bind(this),
  24. this.processReject.bind(this),
  25. reason,
  26. PromiseState.rejected
  27. )
  28. }
  29. // 原有的 resolve 和 reject
  30. private processResolve (value: PromiseData) {
  31. if (this.state === PromiseState.pending) {
  32. this.state = PromiseState.fulfilled
  33. this.data = value
  34. const len = this.onResolvedCallback.length
  35. for (let i = 0; i < len; i++) {
  36. this.onResolvedCallback[i](value)
  37. }
  38. }
  39. }
  40. private processReject (reason: PromiseData) {
  41. if (this.state === PromiseState.pending) {
  42. this.state = PromiseState.rejected
  43. this.data = reason
  44. const len = this.onRejectedCallback.length
  45. for (let i = 0; i < len; i++) {
  46. this.onRejectedCallback[i](reason)
  47. }
  48. }
  49. }
  50. // ...
  51. }

防止等待时多次触发

resolve卡住时要保持状态不变和不能触发 thenable 的回调,这里加一个锁?:

ts
  1. // ...
  2. class ShikaPromise {
  3. // ...
  4. // 用于下面记录 thenable 回调触发情况
  5. private dataOnFulfilledCalled = false
  6. private dataOnRejectedCalled = false
  7. // 这里的?针对 thenable 回调没有触发卡住的情况,thenable 回调会传入什么值我们是不知道的
  8. // 所以用产生 thenable 的 data 来锁一下
  9. private innerThenablePending: PromiseData[] = []
  10. private resolveData (
  11. resolve: Function,
  12. reject: Function,
  13. data: PromiseData,
  14. preData: PromiseData,
  15. targetState: PromiseState.fulfilled | PromiseState.rejected
  16. ) {
  17. if (this.innerThenablePending.length === 0 || this.innerThenablePending[0] === preData) {
  18. this.innerThenablePending = [data]
  19. if (targetState === PromiseState.fulfilled) {
  20. // TODO
  21. } else if (targetState === PromiseState.rejected) {
  22. // reject 的情况下不涉及对 thenable 的处理,直接扔出去
  23. reject(data)
  24. }
  25. }
  26. }
  27. resolve (value: PromiseData) {
  28. this.resolveData(
  29. this.processResolve.bind(this),
  30. this.processReject.bind(this),
  31. value,
  32. undefined,
  33. PromiseState.fulfilled
  34. )
  35. }
  36. reject (reason: PromiseData) {
  37. this.resolveData(
  38. this.processResolve.bind(this),
  39. this.processReject.bind(this),
  40. reason,
  41. undefined,
  42. PromiseState.rejected
  43. )
  44. }
  45. private processResolve (value: PromiseData) {
  46. // 触发了状态改变说明了已经完成了一次 onFulfilled 或者 onRejected 的调用,把锁扔掉
  47. innerThenablePending = []
  48. // ...
  49. }
  50. private processReject (reason: PromiseData) {
  51. innerThenablePending = []
  52. // ...
  53. }
  54. // ...
  55. }

解析 thenable

接下来就是resolve的情况下 Promise Resolution Procedure 的逻辑:

ts
  1. class ShikaPromise {
  2. // ...
  3. private dataOnFulfilledCalled = false
  4. private dataOnRejectedCalled = false
  5. private innerThenablePending: PromiseData[] = []
  6. private resolveData (
  7. resolve: Function,
  8. reject: Function,
  9. data: PromiseData,
  10. preData: PromiseData,
  11. targetState: PromiseState.fulfilled | PromiseState.rejected
  12. ) {
  13. if (this.innerThenablePending.length === 0 || this.innerThenablePending[0] === preData) {
  14. this.innerThenablePending = [data]
  15. if (targetState === PromiseState.fulfilled) {
  16. if (this === data) {
  17. // 不能我自己返回我自己
  18. reject(new TypeError('Cannot resolve self!'))
  19. } else if (data instanceof ShikaPromise) {
  20. // ShikaPromise,直接执行 then 方法
  21. try {
  22. data.then(resolve, reject)
  23. } catch (error) {
  24. reject(error)
  25. }
  26. } else if (typeof data === 'object' || typeof data === 'function') {
  27. // 其他 thenable 的逻辑
  28. let thenMethod: Function
  29. try {
  30. // 规范里面 data.then 只能取一次
  31. thenMethod = data?.then
  32. } catch (error) {
  33. reject(error)
  34. return
  35. }
  36. if (typeof thenMethod === 'function') {
  37. try {
  38. thenMethod.call(data, (y: PromiseData) => {
  39. // onFulfilledCalled、onRejectedCalled 只能最多各调用一次
  40. if (
  41. (!this.dataOnFulfilledCalled || !this.dataOnRejectedCalled)
  42. ) {
  43. this.dataOnFulfilledCalled = true
  44. // 递归直至 thenable 解析完
  45. this.resolveData(
  46. resolve,
  47. reject,
  48. y,
  49. data,
  50. PromiseState.fulfilled
  51. )
  52. }
  53. }, (y: PromiseData) => {
  54. if (
  55. (!this.dataOnFulfilledCalled || !this.dataOnRejectedCalled)
  56. ) {
  57. this.dataOnRejectedCalled = true
  58. // 错误的,直接扔出去,调用 resolveData 主要是处理已有 thenable 待解析的情况
  59. this.resolveData(
  60. resolve,
  61. reject,
  62. y,
  63. data,
  64. PromiseState.rejected
  65. )
  66. }
  67. })
  68. } catch (error) {
  69. // 错误的,直接扔出去,调用 resolveData 主要是处理已有 thenable 待解析的情况
  70. this.resolveData(
  71. resolve,
  72. reject,
  73. error,
  74. data,
  75. PromiseState.rejected
  76. )
  77. }
  78. } else {
  79. // 有 then 但不是方法
  80. resolve(data)
  81. }
  82. } else {
  83. // 不是 object 或者 function
  84. resolve(data)
  85. }
  86. } else if (targetState === PromiseState.rejected) {
  87. reject(data)
  88. }
  89. }
  90. }
  91. // ...
  92. }

其他方法

JS 的 Promise

下面就来实现一下 JS 的 Promse 的catchfinallycatch就是then方法只提供第二个参数。finally方法回调函数不接收任何参数,返回一个状态和数据与原来相同的 Promise。

ts
  1. // ...
  2. class ShikaPromise {
  3. // ...
  4. catch (onRejected: Function) {
  5. return this.then(undefined, onRejected)
  6. }
  7. finally (onFinally: Function) {
  8. const onFulfilled = value => {
  9. onFinally()
  10. return value
  11. }
  12. const onRejected = reason => {
  13. onFinally()
  14. throw reason
  15. }
  16. return this.then(onFulfilled, onRejected)
  17. }
  18. // ...
  19. }

还有Promise.resolvePromise.reject两个静态方法:

ts
  1. // ...
  2. class ShikaPromise {
  3. // ...
  4. static resolve (value?: PromiseData) {
  5. return new ShikaPromise((resolve: Function) => {
  6. resolve(value)
  7. })
  8. }
  9. static reject (reason?: PromiseData) {
  10. return new ShikaPromise((resolve: Function, reject: Function) => {
  11. reject(reason)
  12. })
  13. }
  14. // ...
  15. }

如果 Promise 可以停止

如果想要 Promise 后面的thencatchfinally)都不会触发,这里只需要返回一个 pending 状态的 Promise。这里实现一个时链式调用停止的cancel方法和返回 pending 的 Promise 的wait方法:

ts
  1. // ...
  2. class ShikaPromise {
  3. // ...
  4. cancel (value?: PromiseData) {
  5. return this.then(() => new ShikaPromise(() => {}), () => new ShikaPromise(() => {}))
  6. }
  7. static wait () {
  8. return new ShikaPromise(() => {})
  9. }
  10. // ...
  11. }

Promise A+ 测试

下载 promises-aplus-tests 包:

cmd
  1. npm i promises-aplus-tests

要求 Promise 所在文件采用 commonjs 方式导出。还需要在 Promise 上实现静态方法:

ts
  1. // ...
  2. class ShikaPromise {
  3. // ...
  4. static deferred () {
  5. const testPromise = new ShikaPromise(() => {})
  6. return {
  7. promise: testPromise,
  8. resolve: testPromise.resolve.bind(testPromise),
  9. reject: testPromise.reject.bind(testPromise),
  10. }
  11. }
  12. // ...
  13. }

promises-aplus-tests Promis 所在文件即可运行,如果你在用 TS,文件为编译后的文件,例如:

cmd
  1. promises-aplus-tests dist/ShikaPromise.js

Promise A+ 的测试用例覆盖面非常全,调试时烦死了x,通过了所有 817 条用例,就说明你的 Promise 实现了 Promise A+ 标准了。

我把 TS 编译和运行测试用例在 package.json 组装成一条命令:

json
  1. {
  2. // ...
  3. "scripts": {
  4. // ...
  5. "test": "tsc && promises-aplus-tests dist/ShikaPromise.js",
  6. },
  7. // ...
  8. }

这里 tsc 会默认编译 tsconfig.json 设置的根目录(这里是 ./src),然后放到输出目录中(这里是 ./dist)。

最终实现

ts
  1. enum PromiseState {
  2. fulfilled = 'fulfilled',
  3. pending = 'pending',
  4. rejected = 'rejected'
  5. }
  6. type PromiseData = any
  7. type ThenCallback = any
  8. class ShikaPromise {
  9. // 记录 fulfilled 或者 rejected 后执行的回调函数,将会用于修改 then 方法返回的 Promise 的 data
  10. private onResolvedCallback: Function[] = []
  11. private onRejectedCallback: Function[] = []
  12. data: PromiseData = undefined
  13. state: PromiseState = PromiseState.pending
  14. constructor (executor: Function) {
  15. try {
  16. executor(this.resolve.bind(this), this.reject.bind(this))
  17. } catch(error) {
  18. this.reject(error)
  19. }
  20. }
  21. private dataOnFulfilledCalled = false
  22. private dataOnRejectedCalled = false
  23. private innerThenablePending: PromiseData[] = []
  24. private resolveData (
  25. resolve: Function,
  26. reject: Function,
  27. data: PromiseData,
  28. preData: PromiseData = undefined,
  29. targetState: PromiseState.fulfilled | PromiseState.rejected
  30. ) {
  31. if (this.innerThenablePending.length === 0 || this.innerThenablePending[0] === preData) {
  32. this.innerThenablePending = [data]
  33. if (targetState === PromiseState.fulfilled) {
  34. if (this === data) {
  35. reject(new TypeError('Cannot resolve self!'))
  36. } else if (data instanceof ShikaPromise) {
  37. try {
  38. data.then(resolve, reject)
  39. } catch (error) {
  40. reject(error)
  41. }
  42. } else if (typeof data === 'object' || typeof data === 'function') {
  43. let thenMethod: Function
  44. try {
  45. thenMethod = data?.then
  46. } catch (error) {
  47. reject(error)
  48. return
  49. }
  50. if (typeof thenMethod === 'function') {
  51. try {
  52. thenMethod.call(data, (y: PromiseData) => {
  53. if (
  54. (!this.dataOnFulfilledCalled || !this.dataOnRejectedCalled)
  55. ) {
  56. this.dataOnFulfilledCalled = true
  57. this.resolveData(
  58. resolve,
  59. reject,
  60. y,
  61. data,
  62. PromiseState.fulfilled
  63. )
  64. }
  65. }, (y: PromiseData) => {
  66. if (
  67. (!this.dataOnFulfilledCalled || !this.dataOnRejectedCalled)
  68. ) {
  69. this.dataOnRejectedCalled = true
  70. this.resolveData(
  71. resolve,
  72. reject,
  73. y,
  74. data,
  75. PromiseState.rejected
  76. )
  77. }
  78. })
  79. } catch (error) {
  80. this.resolveData(
  81. resolve,
  82. reject,
  83. error,
  84. data,
  85. PromiseState.rejected
  86. )
  87. }
  88. } else {
  89. resolve(data)
  90. }
  91. } else {
  92. resolve(data)
  93. }
  94. } else if (targetState === PromiseState.rejected) {
  95. reject(data)
  96. }
  97. }
  98. }
  99. resolve (value: PromiseData) {
  100. this.resolveData(
  101. this.processResolve.bind(this),
  102. this.processReject.bind(this),
  103. value,
  104. undefined,
  105. PromiseState.fulfilled
  106. )
  107. }
  108. reject (reason: PromiseData) {
  109. this.resolveData(
  110. this.processResolve.bind(this),
  111. this.processReject.bind(this),
  112. reason,
  113. undefined,
  114. PromiseState.rejected
  115. )
  116. }
  117. private processResolve (value: PromiseData) {
  118. this.innerThenablePending = []
  119. if (this.state === PromiseState.pending) {
  120. this.state = PromiseState.fulfilled
  121. this.data = value
  122. const len = this.onResolvedCallback.length
  123. for (let i = 0; i < len; i++) {
  124. this.onResolvedCallback[i](value)
  125. }
  126. }
  127. }
  128. private processReject (reason: PromiseData) {
  129. this.innerThenablePending = []
  130. if (this.state === PromiseState.pending) {
  131. this.state = PromiseState.rejected
  132. this.data = reason
  133. const len = this.onRejectedCallback.length
  134. for (let i = 0; i < len; i++) {
  135. this.onRejectedCallback[i](reason)
  136. }
  137. }
  138. }
  139. private processFinish (
  140. resolve: Function,
  141. reject: Function,
  142. onFulfilledCallback: Function
  143. ) {
  144. process.nextTick(() => {
  145. try {
  146. const x = onFulfilledCallback(this.data)
  147. resolve(x)
  148. } catch (error) {
  149. reject(error)
  150. }
  151. })
  152. }
  153. then (onFulfilled?: ThenCallback, onRejected?: ThenCallback) {
  154. const onFulfilledCallback = typeof onFulfilled !== 'function'
  155. ? (value: PromiseData) => value
  156. : onFulfilled
  157. const onRejectedCallback = typeof onRejected !== 'function'
  158. ? (reason: PromiseData) => {
  159. throw reason
  160. }
  161. : onRejected
  162. switch (this.state) {
  163. case PromiseState.fulfilled: {
  164. return new ShikaPromise((resolve: Function, reject: Function) => {
  165. this.processFinish(
  166. resolve,
  167. reject,
  168. onFulfilledCallback
  169. )
  170. })
  171. }
  172. case PromiseState.rejected: {
  173. return new ShikaPromise((resolve: Function, reject: Function) => {
  174. this.processFinish(
  175. resolve,
  176. reject,
  177. onRejectedCallback
  178. )
  179. })
  180. }
  181. default: {
  182. return new ShikaPromise((resolve: Function, reject: Function) => {
  183. this.onResolvedCallback.push(() => {
  184. this.processFinish(
  185. resolve,
  186. reject,
  187. onFulfilledCallback
  188. )
  189. })
  190. this.onRejectedCallback.push(() => {
  191. this.processFinish(
  192. resolve,
  193. reject,
  194. onRejectedCallback
  195. )
  196. })
  197. })
  198. }
  199. }
  200. }
  201. catch (onRejected: Function) {
  202. return this.then(undefined, onRejected)
  203. }
  204. finally (onFinally: Function) {
  205. const onFulfilled = value => {
  206. onFinally()
  207. return value
  208. }
  209. const onRejected = reason => {
  210. onFinally()
  211. throw reason
  212. }
  213. return this.then(onFulfilled, onRejected)
  214. }
  215. static resolve (value?: PromiseData) {
  216. return new ShikaPromise((resolve: Function) => {
  217. resolve(value)
  218. })
  219. }
  220. static cancel (value?: PromiseData) {
  221. return this.then(() => new ShikaPromise(() => {}), () => new ShikaPromise(() => {}))
  222. }
  223. static reject (reason?: PromiseData) {
  224. return new ShikaPromise((resolve: Function, reject: Function) => {
  225. reject(reason)
  226. })
  227. }
  228. static wait () {
  229. return new ShikaPromise(() => {})
  230. }
  231. static deferred () {
  232. const testPromise = new ShikaPromise(() => {})
  233. return {
  234. promise: testPromise,
  235. resolve: testPromise.resolve.bind(testPromise),
  236. reject: testPromise.reject.bind(testPromise),
  237. }
  238. }
  239. }

结尾

这里实现了一个 Promise A+ 规范的 Promise。写了好多啊,就不写结尾了吧。

0 条评论未登录用户
Ctrl or + Enter 评论
© 2023-2025 LittleRangiferTarandus, All rights reserved.
🌸 Run