Promise

v1:基本实现

  1. // 最基础的Promise
  2. var pending = 0;
  3. var fulfilled = 1;
  4. var rejected = 2;
  5. function Promisee(fn) {
  6. var state = pending;
  7. var value = null;
  8. function fulfill(result) {
  9. state = fulfilled;
  10. value = result;
  11. }
  12. function reject(err) {
  13. state = reject;
  14. value = err;
  15. }
  16. fn(fulfill, reject);
  17. this.then = function (onFulfilled, onRejected) {
  18. if (state === fulfilled) {
  19. onFulfilled(value);
  20. }
  21. if (state === rejected) {
  22. onRejected(value);
  23. }
  24. };
  25. }
  26. var p = new Promisee((resove, reject) => {
  27. resove('hello world');
  28. }).then((res) => {
  29. console.log(res);
  30. });

v2:加上异步机制

  1. // 使 promse 具有异步功能
  2. var pending = 0;
  3. var fulfilled = 1;
  4. var rejected = 2;
  5. function Promisee(fn) {
  6. var state = pending;
  7. var value = null;
  8. var handler = [];
  9. function fulfill(result) {
  10. state = fulfilled;
  11. value = result;
  12. handler.forEach((handle) => handle.onFulfilled(result));
  13. }
  14. function reject(err) {
  15. state = reject;
  16. value = err;
  17. handler.forEach((handle) => handle.onRejected(err));
  18. }
  19. fn(fulfill, reject);
  20. this.then = function (onFulfilled, onRejected) {
  21. if (state === pending) {
  22. handler.push({ onFulfilled, onRejected });
  23. }
  24. if (state === fulfilled) {
  25. onFulfilled(value);
  26. }
  27. if (state === rejected) {
  28. onRejected(value);
  29. }
  30. };
  31. }
  32. var p = new Promisee((resove, reject) => {
  33. setTimeout(() => {
  34. resove('hello world promise');
  35. }, 200);
  36. }).then((res) => {
  37. console.log(res);
  38. });

v3 :链式调用

  1. // 使 promise 链式调用
  2. function Promisee(fn) {
  3. var pending = 0;
  4. var fulfilled = 1;
  5. var rejected = 2;
  6. var handler = [];
  7. var state = pending;
  8. var value = null;
  9. function fulfill(result) {
  10. state = fulfilled;
  11. value = result;
  12. console.log(handler);
  13. handler.forEach((handle) => handle.onFulfilled(result));
  14. }
  15. function reject(err) {
  16. state = reject;
  17. value = err;
  18. handler.forEach((handle) => handle.onRejected(err));
  19. }
  20. fn(fulfill, reject);
  21. this.then = function (onFulfilled, onRejected) {
  22. return new Promisee((resolve, reject) => {
  23. const fulfillFn = (value) => resolve(onFulfilled(value));
  24. const rejectFn = (err) => reject(onRejected(err));
  25. if (state === pending) {
  26. handler.push({ onFulfilled: fulfillFn, onRejected: rejectFn });
  27. }
  28. if (state === fulfilled) {
  29. resolve(fulfillFn);
  30. }
  31. if (state === rejected) {
  32. reject(rejectFn);
  33. }
  34. });
  35. };
  36. }
  37. var p = new Promisee((resove, reject) => {
  38. setTimeout(() => {
  39. resove('hello world promise');
  40. }, 200);
  41. })
  42. .then((res) => {
  43. console.log(res + 'abc');
  44. return res + 12345;
  45. })
  46. .then((res2) => {
  47. return res2 + 67890;
  48. })
  49. .then((res3) => {
  50. console.log(res3);
  51. });

v4 :支持中途 promise 返回

  1. // return 支持 promise 返回值
  2. class Promisee {
  3. constructor(fn) {
  4. this.pending = 0;
  5. this.fulfilled = 1;
  6. this.rejected = 2;
  7. this.handler = [];
  8. this.state = this.pending;
  9. this.value = null;
  10. const fulfill = (result) => {
  11. this.state = this.fulfilled;
  12. this.value = result;
  13. this.handler.forEach((handle) => handle.onFulfilled(result));
  14. };
  15. const reject = (err) => {
  16. this.state = reject;
  17. this.value = err;
  18. this.handler.forEach((handle) => handle.onRejected(err));
  19. };
  20. const getThen = (value) => {
  21. const t = typeof value;
  22. if (t === 'object' || t === 'function') {
  23. var then = value.then;
  24. if (typeof then === 'function') {
  25. return then;
  26. }
  27. } else {
  28. return null;
  29. }
  30. };
  31. const resolve = (result) => {
  32. const then = getThen(result);
  33. if (then) {
  34. then.call(result, resolve, reject);
  35. return;
  36. }
  37. fulfill(result);
  38. };
  39. fn(resolve, reject);
  40. }
  41. then(onFulfilled, onRejected) {
  42. return new Promisee((resolve, reject) => {
  43. const fulfillFn = (value) => resolve(onFulfilled(value));
  44. const rejectFn = (err) => reject(onRejected(err));
  45. if (this.state === this.pending) {
  46. this.handler.push({ onFulfilled: fulfillFn, onRejected: rejectFn });
  47. }
  48. if (this.state === this.fulfilled) {
  49. fulfillFn(this.value);
  50. }
  51. if (this.state === this.rejected) {
  52. rejectFn(this.value);
  53. }
  54. });
  55. }
  56. static resolve = function (value) {
  57. return new Promisee(function (resolve) {
  58. resolve(value);
  59. });
  60. };
  61. }
  62. console.log('a');
  63. var p = new Promisee((resove, reject) => {
  64. // setTimeout(() => {
  65. resove('hello world promise');
  66. // }, 200);
  67. })
  68. .then((res) => {
  69. console.log('b');
  70. return res + 12345;
  71. })
  72. .then((res2) => {
  73. return Promisee.resolve(res2);
  74. })
  75. .then((res3) => {
  76. console.log(res3, 'xxx');
  77. });
  78. console.log('c');

v5: 支持微任务机制

  1. // return 添加微任务机制
  2. class Promisee {
  3. constructor(fn) {
  4. this.pending = 0;
  5. this.fulfilled = 1;
  6. this.rejected = 2;
  7. this.handler = [];
  8. this.state = this.pending;
  9. this.value = null;
  10. const fulfill = (result) => {
  11. this.state = this.fulfilled;
  12. this.value = result;
  13. this.handler.forEach((handle) => handle.onFulfilled(result));
  14. };
  15. const reject = (err) => {
  16. this.state = this.rejected;
  17. this.value = err;
  18. this.handler.forEach((handle) => handle.onRejected(err));
  19. };
  20. const getThen = (value) => {
  21. const t = typeof value;
  22. if (t === 'object' || t === 'function') {
  23. var then = value.then;
  24. if (typeof then === 'function') {
  25. return then;
  26. }
  27. } else {
  28. return null;
  29. }
  30. };
  31. const resolve = (result) => {
  32. try {
  33. const then = getThen(result);
  34. if (then) {
  35. then.call(result, resolve, reject);
  36. return;
  37. }
  38. fulfill(result);
  39. } catch (err) {
  40. reject(err);
  41. }
  42. };
  43. fn(resolve, reject);
  44. }
  45. done(fulfillFn, rejectFn) {
  46. queueMicrotask(() => {
  47. if (this.state === this.pending) {
  48. this.handler.push({ onFulfilled: fulfillFn, onRejected: rejectFn });
  49. }
  50. if (this.state === this.fulfilled) {
  51. fulfillFn(this.value);
  52. }
  53. if (this.state === this.rejected) {
  54. rejectFn(this.value);
  55. }
  56. });
  57. }
  58. then(onFulfilled, onRejected) {
  59. return new Promisee((resolve, reject) => {
  60. let fulfillFn, rejectFn;
  61. if (typeof onFulfilled === 'function') {
  62. fulfillFn = (value) => resolve(onFulfilled(value));
  63. } else {
  64. fulfillFn = (value) => resove(value);
  65. }
  66. if (typeof onRejected === 'function') {
  67. rejectFn = (err) => reject(onRejected(err));
  68. } else {
  69. rejectFn = (value) => reject(value);
  70. }
  71. this.done(fulfillFn, rejectFn);
  72. });
  73. }
  74. catch(onRejected) {
  75. return this.then(null, onRejected);
  76. }
  77. static resolve = function (value) {
  78. return new Promisee(function (resolve) {
  79. resolve(value);
  80. });
  81. };
  82. }
  83. console.log('a');
  84. var p = new Promisee((resove, reject) => {
  85. setTimeout(() => {
  86. resove('hello world promise');
  87. }, 200);
  88. })
  89. .then((res) => {
  90. throw new Error('this is error');
  91. })
  92. .then((res2) => {
  93. return Promisee.resolve(res2);
  94. })
  95. .catch((err) => {
  96. console.log(err);
  97. });
  98. console.log('c');