https://juejin.cn/post/6844904063570542599

Promise

三种状态

pending

fulfilled

rejected

执行流程

image.png

优点:

统一异步API

Promise与事件对比, 更适合处理一次性的结果

解决回调地狱

更好的错误处理方式

缺点:

无法取消

不设置回调函数, promise内部抛出错误反应到外部

pending状态, 无法得知进展到哪一个阶段

报错堆栈上下文不太友好

依据Promise/A+规范
自身状态
1、state 存放当前的状态。
2、value 存放当前状态的值。

简介版

6个主要属性。 state、value、reason、reslove、reject、then

  1. function MyPromise(executor) {
  2. this.state = "pending";
  3. this.value;
  4. this.state;
  5. let resolve = (value) => {
  6. if (this.state === 'pending') {
  7. this.state = 'fulfilled';
  8. this.value = value;
  9. }
  10. }
  11. let reject = (reason) => {
  12. if (this.state === 'pending') {
  13. this.state = 'rejected';
  14. this.reason = reason;
  15. }
  16. }
  17. try {
  18. executor(reslove, reject); // 立即执行函数
  19. } catch (e) {
  20. reject(e)
  21. }
  22. }
  23. MyPromise.prototype.then = function (onFulfilled, onRejected) {
  24. if (this.state === 'fulfilled') {
  25. onFulfilled(this.value)
  26. }
  27. if (this.state === 'rejected') {
  28. onRejected(this.reason)
  29. }
  30. }

基础版 (重要)

  1. // 基础版
  2. const PENDING = 'pending';
  3. const FULFILLED = 'fulfilled';
  4. const REJECTED = 'rejected';
  5. function MyPromise(executor) {
  6. this.state = PENDING; // 状态
  7. this.value = undefined; // 成功状态的值
  8. this.reason = undefined; // 失败状态的值
  9. this.onFulfilledCallbacks = []; // 存放fulfilled对应的onFulfilled函数
  10. this.onRejectedCallbacks = []; // 存放rejected对应的onRejected函数
  11. let resolve = value => {
  12. if (value instanceof Promise) {
  13. return value.then(resolve, reject);
  14. }
  15. // 确保异步执行
  16. setTimeout (() => {
  17. if (this.state == PENDING) {
  18. this.state = FULFILLED;
  19. this.value = value;
  20. this.onFulfilledCallbacks.forEach(cb => cb(this.value))
  21. }
  22. }, 0)
  23. }
  24. let reject = reason => {
  25. setTimeout (() => {
  26. if (this.state == PENDING) {
  27. this.state = REJECTED;
  28. this.reason = reason;
  29. this.onRejectedCallbacks.forEach(cb => cb(this.reason))
  30. }
  31. }, 0)
  32. }
  33. try {
  34. executor(resolve, reject);
  35. } catch (error) {
  36. reject(error);
  37. }
  38. }
  39. MyPromise.prototype.then = function (onFulfilled, onRejected) {
  40. let promise2;
  41. // 处理参数默认值, 保证后续继续执行
  42. onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
  43. onRejected = typeof onRejected === 'function' ? onRejected : reason => {
  44. throw reason;
  45. };
  46. if (this.state === FULFILLED) {
  47. return promise2 = new Promise((resolve, reject) => {
  48. setTimeout(() => {
  49. try {
  50. let x = onFulfilled(this.value);
  51. this.reslovePromise(promise2, x, resolve, reject)
  52. } catch (error) {
  53. reject(error)
  54. }
  55. }, 0)
  56. })
  57. }
  58. if (this.state === REJECTED) {
  59. return promise2 = new Promise((resolve, reject) => {
  60. setTimeout(() => {
  61. try {
  62. let x = onRejected(this.value);
  63. this.reslovePromise(promise2, x, resolve, reject)
  64. } catch (error) {
  65. reject(error)
  66. }
  67. }, 0)
  68. })
  69. }
  70. if (this.state === PENDING) {
  71. // 等待promise状态暂存后再处理
  72. return promise2 = new Promise((resolve, reject) => {
  73. this.onFulfilledCallbacks.push((value) => {
  74. try {
  75. let x = onFulfilled(value);
  76. this.resolvePromise(promise2, x, resolve, reject)
  77. } catch (error) {
  78. reject(error)
  79. }
  80. });
  81. this.onRejectedCallbacks.push((value) => {
  82. try {
  83. let x = onRejected(reason);
  84. this.resolvePromise(promise2, x, resolve, reject)
  85. } catch (error) {
  86. reject(error)
  87. }
  88. })
  89. });
  90. }
  91. }
  92. // 测试
  93. new MyPromise((resolve, reject) => {
  94. setTimeout(() => {
  95. resolve(1)
  96. },0)
  97. }).then(value => {
  98. console.log('fulfilled', value);
  99. })
  100. new MyPromise((resolve, reject) => {
  101. setTimeout(() => {
  102. reject(2)
  103. },0)
  104. }).then(value => {
  105. // console.log('fulfilled', value);
  106. }, reject => {
  107. console.log('rejected', reject);
  108. })

1、实现一个 promise ,在 setTimeout 中去 resolve。 ok
2、实现一个 promise,直接同步 resolve。 ok
3、实现一个 promise,防止 resolve 多次。 ok
4、实现一个 promise,可以让 then 方法链式调用。 ok
5、实现一个 promise,支持空 then 函数。 ok
6、实现一个 promise,支持 then 传递 thenable 对象。 ok
7、实现一个 promise,支持 then 传递 promise 对象。 ok
8、实现一个 promise,支持 resolve 传递 promise 对象。 ok
9、实现一个 promise,处理 then 中的循环 promise。 ok
10、实现一个 promise,支持静态方法 Promise.all。 ok
11、实现一个 promise,支持 reject 和 catch。 ok
12、实现一个 promise,支持处理完成态或失败态的then。 ok

原型方法

Promise.prototype.then(onFulfilled[, onRejected])

返回一个promise, 两个参数分别是成功/失败回调函数

  1. const p = new Promise((resolve, reject) => {
  2. })
  3. p.then((res) => {
  4. console.log(res)
  5. }).catch((error) => {
  6. console.log(error)
  7. })

then方法链式调用

  1. MyPromise.prototype.then = function (onFulfilled, onRejected) {
  2. if (this.state == PENDING) {
  3. this.onRresolvedCallbacks.push(onFulfilled);
  4. this.onEjectedCallbacks.push(onRejected);
  5. }
  6. if (this.state == FULFILLED) {
  7. onFulfilled(this.value)
  8. }
  9. if (this.state == REJECTED) {
  10. onRejected(this.reason)
  11. }
  12. }

then方法支持多次调用

  1. MyPromise.prototype.then = function (onFulfilled, onRejected) {
  2. // 格式检查, 如果不是函数
  3. onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function (value) {};
  4. onRejected = typeof onRejected === 'function' ? onRejected : function (reason) {};
  5. let promise2 = new Promise((resolve, reject) => {
  6. if (this.state === FULFILLED) {
  7. }
  8. if (this.state === REJECTED) {
  9. }
  10. if (this.state === PENDING) {
  11. // 等待promise状态后再处理
  12. }
  13. })
  14. }

Promise.prototype.catch(onRejected)

Promise.prototype.then(undefined, onRejected)简写。返回一个promise, 参数是失败回调函数。

  1. p.catch((error) => {
  2. console.log(error)
  3. })

catch实现

  1. MyPromise.prototype.catch = function (onRejected) {
  2. return this.then(null, onRejcted)
  3. }

Promise.prototype.finally(onFinally)

与Promise.prototype.finally(onFinally, onFinally)。 返回一个promise, 一个参数是成功/失败回调函数。
适用场景: 关闭加载动画

  1. fetch()
  2. .then()
  3. .catch()
  4. .finally(() => {
  5. isLoading = false
  6. })

方法

Promise.race(iterable)

返回一个promise, 一旦迭代器中有一个promise成功/失败, 则返回1已成功/失败的promise

Promise.all(iterable)

等待全部完成/第一个是失败

Promise.allSettled(iterable)

Promise.allSettled 了解吗?动手实现一下 Promise.allSettled
返回promise组成的数组, 等待迭代器全部元素的成功/失败。

其他方法

Promise.resolve()

Promise.reject()

参考:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/race
https://juejin.im/post/5b2f02cd5188252b937548ab
https://juejin.cn/post/6844903788826853389