作者:奥兰度

    1. // 异步 Promise + 错误处理 + 链式
    2. // new Promise(() => {}).then(() => { return 0}).then((val) => { /* 0 */ })
    3. class MyPromise {
    4. constructor (executor) {
    5. this.status = 'pending'
    6. this.value = undefined // resolve value
    7. this.reason = undefined // reject error
    8. // 存放 then 成功和失败的回调,延后运行
    9. this.onResolveCallbacks = [] // then(() => {}, () => {})
    10. this.onRejectedCallbacks = [] // catch((err) => {})
    11. let resolve = (value) => {
    12. if (this.status === 'pending') {
    13. this.status = 'resolved'
    14. if (value instanceof MyPromise) {
    15. setTimeout(()=> {
    16. const then = value.then
    17. if (typeof then === 'function') {
    18. then.call(value, val => {
    19. this.value = val
    20. }, err => {
    21. if (called) return
    22. called = true
    23. this.reason = err
    24. })
    25. }
    26. })
    27. } else {
    28. this.value = value
    29. }
    30. // 收集的回调运行一下
    31. this.onResolveCallbacks.forEach(fn => fn())
    32. }
    33. }
    34. let reject = (reason) => {
    35. if (this.status === 'pending') {
    36. this.status = 'rejected'
    37. this.reason = reason
    38. // 收集的回调运行一下
    39. this.onRejectedCallbacks.forEach(fn => fn())
    40. }
    41. }
    42. try {
    43. executor(resolve, reject)
    44. } catch (e) {
    45. reject(e)
    46. }
    47. }
    48. then(onFullFilled, onRejected) {
    49. onFullFilled = typeof onFullFilled === 'function' ? onFullFilled : value => value
    50. onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }
    51. let transPromise
    52. transPromise = new MyPromise((resolve, reject) => {
    53. if (this.status === 'resolved') {
    54. try {
    55. setTimeout(() => {
    56. // resolve 后的 then 中 onFullFilled 返回的值是下一个 then 的 onFullFilled 接收的值
    57. if (this.value instanceof MyPromise) {
    58. this.value = this.value.value
    59. }
    60. const value = onFullFilled(this.value)
    61. resolvePromise(transPromise, value, resolve, reject)
    62. })
    63. } catch (e) {
    64. reject(e)
    65. }
    66. }
    67. if (this.status === 'rejected') {
    68. setTimeout(() => {
    69. try {
    70. const value = onRejected(this.reason)
    71. resolvePromise(value)
    72. } catch(e) {
    73. reject(e)
    74. }
    75. })
    76. }
    77. // 收集回调,因为使用了 this 传递,所以值一直存在的
    78. if (this.status === 'pending') {
    79. this.onResolveCallbacks.push(() => {
    80. setTimeout(() => {
    81. try {
    82. if (this.value instanceof MyPromise) {
    83. this.value = this.value.value
    84. }
    85. const value = onFullFilled(this.value)
    86. resolvePromise(transPromise, value, resolve, reject)
    87. } catch (e) {
    88. reject(e)
    89. }
    90. })
    91. })
    92. this.onRejectedCallbacks.push(() => {
    93. setTimeout(() => {
    94. try {
    95. const value = onRejected(this.reason)
    96. resolvePromise(value)
    97. } catch (e) {
    98. reject(e)
    99. }
    100. })
    101. })
    102. }
    103. })
    104. function resolvePromise (transPromise, value, resolve, reject) {
    105. if (transPromise === value) {
    106. return reject(new TypeError('循环引用'))
    107. }
    108. let called // 是否调用成功或失败
    109. // 看 value 是否是个 Promise
    110. if (value !== null && (typeof value === 'object' || typeof value === 'function')) { // value instanceof MyPromise
    111. try {
    112. const then = value.then
    113. if (typeof then === 'function') {
    114. then.call(value, val => {
    115. if (called) return
    116. called = true
    117. resolvePromise(transPromise, val, resolve, reject)
    118. }, err => {
    119. if (called) return
    120. called = true
    121. reject(err)
    122. })
    123. }
    124. } catch (e) {
    125. if (called) return
    126. called = true
    127. reject(e)
    128. }
    129. } else {
    130. resolve(value)
    131. }
    132. }
    133. return transPromise
    134. }
    135. defer () {
    136. let dfd = {}
    137. dfd.promise = new Promise((resolve, reject) => {
    138. dfd.resolve = resolve
    139. dfd.reject = reject
    140. })
    141. return dfd
    142. }
    143. deferred () {
    144. this.defer()
    145. }
    146. }
    147. const myPromiseT = new MyPromise((resolve, reject) => {
    148. // setTimeout(() => {
    149. resolve('foo');
    150. // }, 300);
    151. });
    152. let promiseA = myPromiseT.then(res => {
    153. console.log(res); return res
    154. })
    155. let promiseB = promiseA.then(res => {
    156. console.log(res); return res
    157. })
    158. let promiseC = promiseB.then(res => {
    159. console.log(res); return res
    160. })
    161. console.log('bar')

    作者:

    作者:

    作者: