promise.pptx

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