简易实现

    1. function Promise(executor) {
    2. this.status = 'pending'
    3. this.value = null
    4. this.reason = null
    5. this.onFulfilledArray = []
    6. this.onRejectedArray = []
    7. const resolve = value => {
    8. if (value instanceof Promise) {
    9. return value.then(resolve, reject)
    10. }
    11. setTimeout(() => {
    12. if (this.status === 'pending') {
    13. this.value = value
    14. this.status = 'fulfilled'
    15. this.onFulfilledArray.forEach(func => {
    16. func(value)
    17. })
    18. }
    19. })
    20. }
    21. const reject = reason => {
    22. setTimeout(() => {
    23. if (this.status === 'pending') {
    24. this.reason = reason
    25. this.status = 'rejected'
    26. this.onRejectedArray.forEach(func => {
    27. func(reason)
    28. })
    29. }
    30. })
    31. }
    32. try {
    33. executor(resolve, reject)
    34. } catch(e) {
    35. reject(e)
    36. }
    37. }
    38. Promise.prototype.then = function(onfulfilled, onrejected) {
    39. onfulfilled = typeof onfulfilled === 'function' ? onfulfilled : data => data
    40. onrejected = typeof onrejected === 'function' ? onrejected : error => { throw error}
    41. if (this.status === 'fulfilled') {
    42. onfulfilled(this.value)
    43. }
    44. if (this.status === 'rejected') {
    45. onrejected(this.reason)
    46. }
    47. if (this.status === 'pending') {
    48. this.onFulfilledArray.push(onfulfilled)
    49. this.onRejectedArray.push(onrejected)
    50. }
    51. }

    详细实现

    1. function Promise(executor) {
    2. this.status = 'pending'
    3. this.value = null
    4. this.reason = null
    5. this.onFulfilledArray = []
    6. this.onRejectedArray = []
    7. const resolve = value => {
    8. if (value instanceof Promise) {
    9. return value.then(resolve, reject)
    10. }
    11. setTimeout(() => {
    12. if (this.status === 'pending') {
    13. this.value = value
    14. this.status = 'fulfilled'
    15. this.onFulfilledArray.forEach(func => {
    16. func(value)
    17. })
    18. }
    19. })
    20. }
    21. const reject = reason => {
    22. setTimeout(() => {
    23. if (this.status === 'pending') {
    24. this.reason = reason
    25. this.status = 'rejected'
    26. this.onRejectedArray.forEach(func => {
    27. func(reason)
    28. })
    29. }
    30. })
    31. }
    32. try {
    33. executor(resolve, reject)
    34. } catch(e) {
    35. reject(e)
    36. }
    37. }
    38. const resolvePromise = (promise2, result, resolve, reject) => {
    39. // 当 result 和 promise2 相等时,也就是说 onfulfilled 返回 promise2 时,进行 reject
    40. if (result === promise2) {
    41. return reject(new TypeError('error due to circular reference'))
    42. }
    43. // 是否已经执行过 onfulfilled 或者 onrejected
    44. let consumed = false
    45. let thenable
    46. if (result instanceof Promise) {
    47. if (result.status === 'pending') {
    48. result.then(function(data) {
    49. resolvePromise(promise2, data, resolve, reject)
    50. }, reject)
    51. } else {
    52. result.then(resolve, reject)
    53. }
    54. return
    55. }
    56. let isComplexResult = target => (typeof target === 'function' || typeof target === 'object') && (target !== null)
    57. // 如果返回的是疑似 Promise 类型
    58. if (isComplexResult(result)) {
    59. try {
    60. thenable = result.then
    61. // 如果返回的是 Promise 类型,具有 then 方法
    62. if (typeof thenable === 'function') {
    63. thenable.call(result, function(data) {
    64. if (consumed) {
    65. return
    66. }
    67. consumed = true
    68. return resolvePromise(promise2, data, resolve, reject)
    69. }, function(error) {
    70. if (consumed) {
    71. return
    72. }
    73. consumed = true
    74. return reject(error)
    75. })
    76. }
    77. else {
    78. return resolve(result)
    79. }
    80. } catch(e) {
    81. if (consumed) {
    82. return
    83. }
    84. consumed = true
    85. return reject(e)
    86. }
    87. }
    88. else {
    89. return resolve(result)
    90. }
    91. }
    92. Promise.prototype.then = function(onfulfilled, onrejected) {
    93. onfulfilled = typeof onfulfilled === 'function' ? onfulfilled : data => data
    94. onrejected = typeof onrejected === 'function' ? onrejected : error => {throw error}
    95. // promise2 将作为 then 方法的返回值
    96. let promise2
    97. if (this.status === 'fulfilled') {
    98. return promise2 = new Promise((resolve, reject) => {
    99. setTimeout(() => {
    100. try {
    101. // 这个新的 promise2 resolved 的值为 onfulfilled 的执行结果
    102. let result = onfulfilled(this.value)
    103. resolvePromise(promise2, result, resolve, reject)
    104. }
    105. catch(e) {
    106. reject(e)
    107. }
    108. })
    109. })
    110. }
    111. if (this.status === 'rejected') {
    112. return promise2 = new Promise((resolve, reject) => {
    113. setTimeout(() => {
    114. try {
    115. // 这个新的 promise2 reject 的值为 onrejected 的执行结果
    116. let result = onrejected(this.reason)
    117. resolvePromise(promise2, result, resolve, reject)
    118. }
    119. catch(e) {
    120. reject(e)
    121. }
    122. })
    123. })
    124. }
    125. if (this.status === 'pending') {
    126. return promise2 = new Promise((resolve, reject) => {
    127. this.onFulfilledArray.push(value => {
    128. try {
    129. let result = onfulfilled(value)
    130. resolvePromise(promise2, result, resolve, reject)
    131. }
    132. catch(e) {
    133. return reject(e)
    134. }
    135. })
    136. this.onRejectedArray.push(reason => {
    137. try {
    138. let result = onrejected(reason)
    139. resolvePromise(promise2, result, resolve, reject)
    140. }
    141. catch(e) {
    142. return reject(e)
    143. }
    144. })
    145. })
    146. }
    147. }
    148. Promise.prototype.catch = function(catchFunc) {
    149. return this.then(null, catchFunc)
    150. }
    151. Promise.resolve = function(value) {
    152. return new Promise((resolve, reject) => {
    153. resolve(value)
    154. })
    155. }
    156. Promise.reject = function(value) {
    157. return new Promise((resolve, reject) => {
    158. reject(value)
    159. })
    160. }
    161. Promise.race = function(promiseArray) {
    162. if (!Array.isArray(promiseArray)) {
    163. throw new TypeError('The arguments should be an array!')
    164. }
    165. return new Promise((resolve, reject) => {
    166. try {
    167. const length = promiseArray.length
    168. for (let i = 0; i <length; i++) {
    169. promiseArray[i].then(resolve, reject)
    170. }
    171. }
    172. catch(e) {
    173. reject(e)
    174. }
    175. })
    176. }
    177. Promise.all = function(promiseArray) {
    178. if (!Array.isArray(promiseArray)) {
    179. throw new TypeError('The arguments should be an array!')
    180. }
    181. return new Promise((resolve, reject) => {
    182. try {
    183. let resultArray = []
    184. const length = promiseArray.length
    185. for (let i = 0; i <length; i++) {
    186. promiseArray[i].then(data => {
    187. resultArray.push(data)
    188. if (resultArray.length === length) {
    189. resolve(resultArray)
    190. }
    191. }, reject)
    192. }
    193. }
    194. catch(e) {
    195. reject(e)
    196. }
    197. })
    198. }