1. const PENDING = 'PEINDING'
    2. const REJECTED = 'REJECTED'
    3. const RESOLVE = 'RESOLVE'
    4. const reslovePromise = (promise2, x, resolve, reject) => {
    5. let then = x.then;
    6. let called;
    7. if (typeof then === 'function') {
    8. then.call(x, y => { // 根据 promise 的状态决定是成功还是失败
    9. if (called) return;
    10. called = true;
    11. resolvePromise(promise2, y, resolve, reject);
    12. }, r => {
    13. if (called) return;
    14. called = true;
    15. reject(r);
    16. });
    17. } else {
    18. resolve(x);
    19. }
    20. }
    21. Promise {
    22. constructor (executor) {
    23. this.status = PENGDING
    24. this.value = null
    25. this.reson = null
    26. this.onRejectCallbacks = []
    27. this.onResovlveCallBacks = []
    28. let resolve = (value) {
    29. if (this.staus === PENDING) {
    30. this.status = RESOLVE
    31. this.value = value
    32. this.onResovleCallbacks.forEach((fn) => fn())
    33. }
    34. }
    35. let reject = (reason) {
    36. if (this.status === PENDING) {
    37. this.staus = REJECTED
    38. this.reason = reason
    39. this.onRejectCallbacks.forEach((fn) => fn())
    40. }
    41. }
    42. try {
    43. executor(resolve, reject)
    44. }catch (err){
    45. reject(err)
    46. }
    47. }
    48. then (onResolve, onReject) {
    49. onResolve = typeOf onResolve === 'function' ? onResolve : v => v
    50. onReject = typeOf onReject === 'function' ? onReject : err => {throw err}
    51. // then穿透
    52. const promise2 = new Promise(async (resolve, reject) => {
    53. if (this.staus === RESOLVE) {
    54. try {
    55. let x = await onResolve(this.value)
    56. reslovePromise(promise2,x,resolve, reject)
    57. } catch(err) {
    58. reject(err)
    59. }
    60. }
    61. if (this.status === REJECTED) {
    62. try {
    63. let x = await onResolve(this.reason)
    64. reslovePromise(promise2,x,resolve, reject)
    65. } catch(err) {
    66. reject(err)
    67. }
    68. }
    69. if (this.status === PENDING) {
    70. this.onResolveCallbacks.push(() => {
    71. try {
    72. let x = await onResolve(this.reason)
    73. reslovePromise(promise2,x,resolve, reject)
    74. } catch(err) {
    75. reject(err)
    76. }
    77. })
    78. this.onRejectCallbacks.push(() => {
    79. try {
    80. let x = await onResolve(this.reason)
    81. reslovePromise(promise2,x,resolve, reject)
    82. } catch(err) {
    83. reject(err)
    84. }
    85. })
    86. }
    87. })
    88. return promise2
    89. }
    90. }