1. const PENDING = 'pending'
    2. const FULFILLED = 'fulfilled'
    3. const REJECTED = 'rejected'
    4. class Promise {
    5. constructor(executor) {
    6. this.state = PENDING
    7. this.value = null
    8. this.reason = null
    9. this.onFulfilledCallbacks = []
    10. this.onRejectedCallbacks = []
    11. const resolve = value => {
    12. setTimeout(() => {
    13. if (this.state === PENDING) {
    14. this.state = FULFILLED
    15. this.value = value
    16. this.onFulfilledCallbacks.forEach(cb => {
    17. cb = cb(this.value)
    18. })
    19. }
    20. });
    21. }
    22. const reject = reason => {
    23. setTimeout(() => {
    24. if (this.state === PENDING) {
    25. this.state = REJECTED
    26. this.reason = reason
    27. this.onRejectedCallbacks.forEach(cb => {
    28. cb = cb(this.reason)
    29. })
    30. }
    31. });
    32. }
    33. try {
    34. executor(resolve, reject)
    35. } catch (e) {
    36. reject(e)
    37. }
    38. }
    39. then(onFulfilled, onRejected) {
    40. onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
    41. onRejected = typeof onRejected === 'function' ? onRejected : reason => {
    42. throw reason
    43. }
    44. let newPromise
    45. if (this.state === FULFILLED) {
    46. return (newPromise = new Promise((resolve, reject) => {
    47. setTimeout(() => {
    48. try {
    49. let x = onFulfilled(this.value)
    50. resolvePromise(newPromise, x, resolve, reject)
    51. } catch (e) {
    52. reject(e)
    53. }
    54. });
    55. }))
    56. }
    57. if (this.state === REJECTED) {
    58. return (newPromise = new Promise((resolve, reject) => {
    59. setTimeout(() => {
    60. try {
    61. let x = onRejected(this.reason)
    62. resolvePromise(newPromise, x, resolve, reject)
    63. } catch (e) {
    64. reject(e)
    65. }
    66. });
    67. }))
    68. }
    69. if (this.state === PENDING) {
    70. return (newPromise = new Promise((resolve, reject) => {
    71. this.onFulfilledCallbacks.push(value => {
    72. try {
    73. let x = onFulfilled(value)
    74. resolvePromise(newPromise, x, resolve, reject)
    75. } catch (e) {
    76. reject(e)
    77. }
    78. })
    79. this.onRejectedCallbacks.push(reason => {
    80. try {
    81. let x = onRejected(reason)
    82. resolvePromise(newPromise, x, resolve, reject)
    83. } catch (e) {
    84. reject(e)
    85. }
    86. })
    87. }))
    88. }
    89. }
    90. }
    91. function resolvePromise(promise2, x, resolve, reject) {
    92. if (x === promise2) {
    93. reject(new TypeError())
    94. }
    95. if (x instanceof Promise) {
    96. if (x.state === PENDING) {
    97. x.then(y => {
    98. resolvePromise(promise2, y, resolve, reject)
    99. }, reason => {
    100. reject(reason)
    101. })
    102. } else {
    103. x.then(resolve, reject)
    104. }
    105. } else if (x && (typeof x === 'function' || typeof x === 'object')) {
    106. let called = false
    107. try {
    108. let then = x.then
    109. if (typeof then === 'function') {
    110. then.call(x, y => {
    111. if (called) return
    112. called = true
    113. resolvePromise(promise2, y, resolve, reject)
    114. }, r => {
    115. if (called) return
    116. called = true
    117. reject(r)
    118. })
    119. } else {
    120. resolve(x)
    121. }
    122. } catch (e) {
    123. if (called) return
    124. called = true
    125. reject(e)
    126. }
    127. } else {
    128. resolve(x)
    129. }
    130. }