一步一步手写promise[三]

港控/mmm° 2022-02-13 08:15 412阅读 0赞

上一篇文章我们已经走到差不多最后一步了,只需要处理如果then接受状态的返回值是一个promise,我们递归处理即可。

最后的代码长这样:

  1. function Promise5(executor) {
  2. this.status = 'pending'
  3. this.value = void 0
  4. this.error = void 0
  5. this.fulFillTasks = []
  6. this.rejectTasks = []
  7. const _resolve = (resolveValue) => {
  8. if (this.status === 'pending') {
  9. this.status = 'resolved'
  10. this.value = resolveValue
  11. this.fulFillTasks.forEach(fn => {
  12. fn && fn(resolveValue)
  13. })
  14. }
  15. }
  16. const _reject = (rejectError) => {
  17. if (this.status === 'pending') {
  18. this.status = 'rejected'
  19. this.error = rejectError
  20. this.rejectTasks.forEach(fn => {
  21. fn && fn(rejectError)
  22. })
  23. }
  24. }
  25. executor(_resolve, _reject)
  26. }
  27. // Promise5.prototype.then = function (onFulfilled, onRejected) {
  28. // if (this.status === 'resolved') {
  29. // return new Promise5((resolve, reject) => {
  30. // setTimeout(() => {
  31. // let val = onFulfilled(this.value)
  32. // resolve(val)
  33. // }, 0)
  34. // })
  35. // }
  36. // if (this.status === 'rejected') {
  37. // return new Promise5((resolve, reject) => {
  38. // let error = onRejected(this.error)
  39. // reject(error)
  40. // }, 0)
  41. // }
  42. // return new Promise5((resolve, reject) => {
  43. // var resolveFunc = (val) => {
  44. // return setTimeout(() => {
  45. // let ret = onFulfilled(val)
  46. // resolve(ret)
  47. // }, 0)
  48. // }
  49. // this.fulFillTasks.push(resolveFunc)
  50. // var rejectFunc = (val) => {
  51. // return setTimeout(() => {
  52. // let errRet = onRejected(err)
  53. // resolve(errRet)
  54. // }, 0)
  55. // }
  56. // this.rejectTasks.push(rejectFunc)
  57. // })
  58. // }
  59. Promise5.prototype.then = function (onFulfilled, onRejected) {
  60. // 可能不是传入的函数,需要处理
  61. onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
  62. onRejected = typeof onRejected === "function" ? onRejected : reason =>{ throw reason };
  63. // onFulfilled 和 onRejected返回的可能是Promise
  64. // ret 是返回值
  65. function resolvePromise(ret, resolve, reject) {
  66. // todo 判断resolve 和 reject是否是函数
  67. // 判断ret是不是promise
  68. if (ret !== null && (typeof ret === 'object')) {
  69. try {
  70. let then = ret.then
  71. if (typeof then === 'function') {
  72. then.call(ret, x => {
  73. resolvePromise(x, resolve, reject)
  74. }, y => {
  75. reject(y)
  76. })
  77. } else {
  78. resolve(ret)
  79. }
  80. } catch (err) {
  81. reject(err)
  82. }
  83. // 不是promise直接resolve onFulfilled的返回值
  84. } else {
  85. resolve(ret)
  86. }
  87. }
  88. if (this.status === 'resolved') {
  89. return new Promise5((resolve, reject) => {
  90. setTimeout(() => {
  91. try {
  92. let ret = onFulfilled(this.value)
  93. // resolve(val)
  94. resolvePromise(ret, resolve, reject)
  95. } catch (e) {
  96. reject(e)
  97. }
  98. }, 0)
  99. })
  100. }
  101. if (this.status === 'rejected') {
  102. return new Promise5((resolve, reject) => {
  103. try {
  104. let errRet = onRejected(this.error)
  105. // reject(error)
  106. resolvePromise(errRet, resolve, reject)
  107. } catch (e) {
  108. reject(e)
  109. }
  110. }, 0)
  111. }
  112. return new Promise5((resolve, reject) => {
  113. var resolveFunc = (val) => {
  114. return setTimeout(() => {
  115. try {
  116. let ret = onFulfilled(val)
  117. // resolve(ret)
  118. resolvePromise(ret, resolve, reject)
  119. } catch (e) {
  120. reject(e)
  121. }
  122. }, 0)
  123. }
  124. this.fulFillTasks.push(resolveFunc)
  125. var rejectFunc = (val) => {
  126. return setTimeout(() => {
  127. try {
  128. let errRet = onRejected(err)
  129. // resolve(errRet)
  130. resolvePromise(errRet, resolve, reject)
  131. } catch (e) {
  132. reject(e)
  133. }
  134. }, 0)
  135. }
  136. this.rejectTasks.push(rejectFunc)
  137. })
  138. }

all code : https://github.com/aeolusheath/FrontExersize/tree/master/pure-js-demo/promise-diy

参考资料:

https://promisesaplus.com/
https://segmentfault.com/a/1190000018335648

发表评论

表情:
评论列表 (有 0 条评论,412人围观)

还没有评论,来说两句吧...

相关阅读