ES6中Promise的一点理解

在了解Promise之前我们需要去了解一下JS的线程机制
其实我们在前后端交互的时候经常会遇到异步处理,函数的回调的情况,现在的前端程序员基本上都会使用ES6的语法,其中就是包含了对Promise函数对象的使用,我们今天也来探讨一下Promise


方向

我们主要从以下几个方面去讨论Promise

  1. Promise是什么
  2. 为什么使用Promise
  3. 如何使用Promise
  4. 如何自定义实现Promise

Promise是什么

基本解释

  1. 抽象含义:
    PromiseJS中进行异步编程时提出的新的解决方案,旧方法就是使用纯回调的方式
  2. 具体表达:
    (1)语法:Promise是一个构造函数对象
    (2)功能:Promise对象一般用来封装一个异步操作并可以获取其值
  3. 官方描述
    Promise 对象用于表示一个异步操作的最终完成 (或失败), 及其结果值.
  4. 包含的状态
    三种状态:pending,resolve,reject

pending -> resolve
pending -> reject

近一步理解

所有Promise的实现都离不开Promise/A+规范
在每一个Promise中,如果状态发生了变化,那么只会变化一次。无论是成功还是失败都有一个返回结果。

术语

  1. Promise 一个拥有 then 方法的对象或函数,其行为符合 Promises/A+ 规范
  2. thenable 一个定义了 then 方法的对象或函数,也可视作 “拥有 then 方法”
  3. 值(value) 指任何 JavaScript 的合法值(包括 undefined , thenablepromise
  4. 异常(exception) 使用 throw 语句抛出的一个值
  5. 据因(reason) 表示一个 promise 的拒绝原因。

我们一般将成功返回的结果称为value,将失败返回的结果称为reason

Promise的运行过程

@flowstart
st=>start: new Promise()【pending】
e=>end: 新promise对象
op1=>operation: 执行异步操作
op2=>operation: 返回promise对象(resolve)【resolved】
op3=>operation: 返回promise对象(reject)【rejected】
op4=>operation: thenable,回调onResolved【resolved】
op5=>operation: thenable,回调onRejected【rejected】
cond=>condition: 成功还是失败?

st(right)->op1(right)->cond
cond(yes)->op2->op4->e
cond(no)->op3->op5->e
@flowend

这个就是promise的运行流程,当构建一个promise对象执行异步操作后,分为两种可能

  1. 成功了,执行resolve(),pending -> resolved。返回promise对象、值,在thenable中回调onResolved函数,最后返回一个新的promise对象
  2. 失败了,执行reject(),pending -> rejeccted。返回promise对象、值,在thenable中回调onResolved函数(也可以使用catch接受exception),最后返回一个新的promise对象

为什么使用Promise

纯回调函数的嵌套使用很糟糕

  1. function doSth() {}
  2. function successCallback(res) {}
  3. function failureCallbacl(err) {}
  4. // 使用纯回调函数的方式,进行调用上述两个方法
  5. doSomeThingAsync(doSth, successCallback, failureCallbacl) {}
  6. // 使用Promise的方式
  7. const promise = doSomeThingAsync(doSth)
  8. setTimeout(() => { // 模拟异步操作
  9. promise.then(successCallback, failureCallbacl)
  10. })

这种方式从语义上面:使用Promise的方式更加具有可读性,可以从函数执行的角度分许,我们是先执行同步函数doSth,再去执行回调函数。使用纯回调的方式执行,并不能比较直观的看出来,函数执行的进程。

关于回调函数的指定,纯回调函数需要在启动异步任务之前就定义好,而Promise的方式是:启动异步任务 => 返回Promise对象 => 给Promise对象绑定回调函数

同时,还有一个比较熟悉的概念:回调地狱问题。

  1. doSomeThingOne(function(resOne) {
  2. doSomeThingTwo(function(resOne, function(resTwo){
  3. doSomeThingThree(function(resTwo, function(resThree) {
  4. console.log('final result' + resThree)
  5. }))
  6. }))
  7. })

上述的代码有一个特点就是,下一个函数的执行以来与上一个函数执行返回的结果,它是串连执行的。可以看到仅有三个回调的时候,里面没有逻辑代码已经看起来很难受,当有多重回调嵌套的时候,会使得代码显示的非常糟糕。我们使用promise进行链式调用就可以解决毁掉地狱的问题。

  1. doSomeThingOne().then( resOne => doSomeThingTwo(resOne)
  2. }).then(resTwo => {
  3. doSomeThingThree( resThree => {
  4. console.log('final result' + resThree)
  5. } )
  6. })

这样我们就可以清楚的看到他们之间的区别。

拓展:我们使用Promise解决回调地狱的问题,还有更好的办法么?

  1. // async/await
  2. function getUserList() {} // 获取服务器端的用户列表,当成一个异步函数
  3. async function _getUserList() {// 定义一个本地私有获取用户列表的方法
  4. try {
  5. const result = await getUserList() // 我们可以使用这种方式获取异步函数回调结果
  6. const data = res.data
  7. } cathc (err) {
  8. console.log(err)
  9. }
  10. }

使用async/await的方式,直接取消回调函数的使用,也是新增ES特性,是终极解决方案。


如何使用Promise

API

Promise的构造函数

Promise (excutor) {}

(1) excutor函数: 执行器 (resolve, reject) => {}
(2) resolve函数: 内部定义成功时,我们调用的函数 value => {}
(3) reject函数: 内部定义失败时,我们调用的函数 reason => {}
说明:excutor 会在Promise内部立即同步执行回调,即异步操作在执行器中的函数中执行

方法

原型上的方法,一般在创建实例对象时候使用

Promise.prototype.then()
Promise.prototype.catch()
Promise.prototype.finally()
Promise.prototype.allSettled()

函数对象上的方法,静态方法可以在由内置的Promise对象直接使用。

Promise.all()
Promise.race()
Promise.reject()
Promise.resolve()
具体方法的含义不是本次的重点,详情请参照MDN-Promise

使用Promise API需要探讨的几个关键问题

  1. Promise的三种状态是如何改变的
    resolve (value):【pending】-> 【resolved】,excutor回调执行成功时调用resolve函数 ,返回成功的值
    reject (reason):【pending】-> 【rejected】,excutor回调执行失败时调用reject函数,返回失败的据因
    throw exception:【pending】-> 【rejected】,在同步执行时抛出异常,直接走失败的回调

  2. 一个Promise同时指定多个成功/失败回调函数,都会调用么
    只要状态发生了改变,就会调用,可以看出状态的改变时promise触发的关键,也是触发promise的依据。

  3. Promise状态的改变 和 执行回调函数的顺序

正常的逻辑是,返回了异步函数的结果 -> 改变状态 -> 执行thenable,但如果这样

  1. new Promise((resolve, reject) => {
  2. setTimeout(() => {
  3. resolve(1) // 后改变状态(同时指定数据),异步执行回调函数
  4. }, 1000)
  5. }).then( // then方法是立即执行的,它会先指定回调函数,如果当前的回调函数是异步执行的函数,会保存当前指定的回调函数
  6. value => { console.log('value', value) },
  7. reason => { console.log('reason', reason) }
  8. )

这种方法是先改变状态再指定回调,但也可以使用同步:

  1. new Promise((resolve, reject) => {
  2. resolve(1) // 先改变状态(同时指定数据)
  3. }).then( // then方法是立即执行的,它会后指定回调函数,异步执行回调函数
  4. value => { console.log('value', value) },
  5. reason => { console.log('reason', reason) }
  6. )

也就是说,顺序是都有可能的,需要分情况讨论

  1. 正常情况下先指定回调再改变状态,但也可以先改变状态再指定回调
    什么时候得到数据?

  2. 如果先指定回调,那当状态发生改变时,回调函数就会调用,得到数据

  3. 如果先改变状态,那当指定回调时,回调函数就会调用,得到数据

  4. Promise.then()返回新的promise的结果状态由什么决定

简述:由then()指定的回调函数执行的结果决定

  1. new Promise((resolve, reject) => {
  2. resolve(1)
  3. // reject(1)
  4. }).then(
  5. value =>{
  6. console.log('onResolved1', value)
  7. // 当前的value是上一个Promise对象返回的值,如果没有定义,只声明那么value就是undefined 相当于 return undefined
  8. // return 2 // value => 2
  9. // return Promise.resolve(2) // value => 2
  10. // return Promise.reject(2) // reason => 2
  11. // throw error // reason => exception
  12. },
  13. reason => {
  14. console.log('onRejected1', reason) // 1
  15. }
  16. ).then(
  17. value =>{
  18. console.log('onResolved2', value) // undefined
  19. },
  20. reason => {
  21. console.log('onRejected2', reason)
  22. }
  23. )

详述:

  1. 如果抛出异常,新的promise的状态由pending -> rejected, reason为抛出的异常
  2. 如果返回的是非promise的任意值,新的promise的状态由pending -> resolved, value为返回的成功值
  3. 如果返回的是一个新的promise,此promise执行的结果和状态决定新promise的状态,保持一致。
  1. Promise如何串连多个同步/异步任务?

使用then()方法,同步直接执行,异步操作需要包装到一个新的promise中作为结果返回

  1. new Promise((resolve, reject) => {
  2. resolve(1)
  3. }).then(value =>{
  4. return new Promise((resolve, reject) => {
  5. setTimeout(() => {
  6. resolve(value)
  7. console.log('异步操作需要包装到一个promise对象中返回'value)
  8. })
  9. })
  10. })
  1. 异常传透
  2. 当使用promisethen的链式调用,可以在最后指定失败的回调函数
  3. 前面任何操作出了异常,都会传递到最后失败的回调中处理
  1. new Promise((resolve, reject) => {
  2. throw 1
  3. }).then(
  4. value => {},
  5. reason => {
  6. throw 1
  7. }
  8. ).then(
  9. value => {},
  10. reason => {
  11. throw 1
  12. }
  13. ).catch(err){
  14. console.log(err)
  15. }

其实这个到底是传透还是穿透看你怎么理解,他是通过层层return到底部那就是传透,如果所有的错误都调用catch来捕获异常那就是穿透。不影响理解

  1. 中断Promise
  2. 当使用promisethen的链式调用,在中间中断,不会再调用后面的回调函数
  3. 办法:在回调函数中返回一个pending状态的promise空对象
  1. return new Promise(() => {}) // 返回一个空promise,默认状态是pending状态,指定一个pending状态的promise即可中断promise的链式调用(thenable)
  1. new Promise((resolve, reject) => {
  2. rejecct(1)
  3. }).then(
  4. value => {},
  5. reason => { // 如果不写,就相当于抛出一个reject的reason
  6. throw reason // reason = 1
  7. }
  8. ).then(
  9. value => {},
  10. reason => {
  11. throw reason // reason = 1
  12. }
  13. ).catch(reason => {
  14. console.log(reason)
  15. return new Promise(() => {}) // 中断promise链,有其他状态 -> pending状态
  16. }).then(
  17. value => {},
  18. reason => {
  19. throw reason // reason = 1
  20. }
  21. )

如何自定义实现Promise

当我们了解了promise相关比较复杂的知识点再去实现一个简单的promise,那么对promise会有一个更深的认识!
ps:这只是一个简单的实现,具体复杂的建议去看源码
基础版本

  1. /* 自定义promise函数模块
  2. 我们使用es5的方法定义模块,如果使用es6语法这样就需要转义
  3. IIFE - 立即执行函数
  4. */
  5. (function(window) {
  6. const PENDING = "pending";
  7. const RESOLVED = "resolved";
  8. const REJECTED = "rejected";
  9. /*
  10. Promise:构造函数
  11. excutor:执行器(同步执行)
  12. */
  13. function Promise(excutor) {
  14. const _this = this;
  15. /*
  16. status:用来存储当前的状态,初始状态是pending
  17. data:给promise对象指定一个用于存储结果数据的属性
  18. callbacks:用于保存{onResolved(){},onRejected(){}}回调
  19. */
  20. _this.status = PENDING;
  21. _this.data = undefined;
  22. _this.callbacks = [];
  23. // 内部定义resolve函数
  24. function resolve(value) {
  25. // 判断当前的状态
  26. if (_this.status !== PENDING) return;
  27. /*
  28. 1.改变状态 pending -> resolved
  29. 2.保存value 将接受的value赋值给data
  30. */
  31. _this.status = RESOLVED;
  32. _this.data = value;
  33. // 如果有待执行的callback函数,立即异步执行回调函数onResolved
  34. if (_this.callbacks.length > 0) {
  35. _this.callbacks.forEach(callbacksObj => {
  36. setTimeout(() => {
  37. //这种写法不太准确,因为setTimeOut属于宏队列元素,但是可以模拟当前需要的异步操作,我们的目的就是将回调函数放入执行stack中异步执行
  38. callbacksObj.onResolved(value);
  39. });
  40. });
  41. }
  42. }
  43. // 内部定义reject函数
  44. function reject(reason) {
  45. /*
  46. 1.改变状态 pending -> rejected
  47. 2.保存reason 将接受的reason赋值给data
  48. */
  49. _this.status = REJECTED;
  50. _this.data = reason;
  51. // 如果有待执行的callback函数,立即异步执行回调函数onRejected
  52. if (_this.callbacks.length > 0) {
  53. _this.callbacks.forEach(callbacksObj => {
  54. setTimeout(() => {
  55. //这种写法不太准确,因为setTimeOut属于宏队列元素,但是可以模拟当前需要的异步操作,我们的目的就是将回调函数放入执行stack中异步执行
  56. callbacksObj.onRejected(reason);
  57. });
  58. });
  59. }
  60. }
  61. // 立即执行excutor
  62. try {
  63. excutor(resolve, reject);
  64. } catch (error) {
  65. // 如果执行器抛出异常,promise对象直接调用rejected
  66. reject(error);
  67. }
  68. }
  69. /*
  70. Promise原型对象的then()
  71. 指定成功和失败的回调函数
  72. 返回一个新的promise对象
  73. 返回的promise的结果有onResolved和onRejected执行结果决定
  74. */
  75. Promise.prototype.then = function(onResolved, onRejected) {
  76. const _this = this;
  77. // 指定回调函数的默认值(必须是函数)
  78. onResolved = typeof onResolved === "function" ? onResolved : value => value;
  79. onRejected = typeof onRejected === "function" ? onRejected : reason => { throw reason};
  80. return new Promise((resolve, reject) => {
  81. /*
  82. 执行指定的回调函数,根据执行的结果改变return的promise的状态
  83. */
  84. function handle(callback) {
  85. // 1.抛出异常
  86. try {
  87. const result = callback(_this.data);
  88. if (result instanceof Promise) {
  89. // 2.如果当前返回的是promise
  90. result.then(resolve, reject);
  91. } else {
  92. // 3.如果返回的不是promise,为一个成功值
  93. resolve(result);
  94. }
  95. } catch (error) {
  96. // 4.如果返回的不是promise,为一个异常值
  97. reject(error);
  98. }
  99. }
  100. if (_this.status === RESOLVED) {
  101. // 当前promise是resolved
  102. setTimeout(() => {
  103. handle(onResolved);
  104. });
  105. } else if (_this.status === REJECTED) {
  106. // 当前promise是rejected
  107. setTimeout(() => {
  108. handle(onRejected);
  109. });
  110. } else {
  111. // 当前promise是pending
  112. // 将成功失败的回调函数保存到callbacks中缓存
  113. _this.callbacks.push({
  114. onResolved() {
  115. handle(onResolved);
  116. },
  117. onRejected() {
  118. handle(onRejected);
  119. }
  120. });
  121. }
  122. });
  123. };
  124. /*
  125. Promise的原型对象的catch()
  126. 指定失败的回调函数,返回一个新的promise对象
  127. */
  128. Promise.prototype.catch = function(onRejected) {
  129. return this.then(undefined, onRejected);
  130. };
  131. /*
  132. Promise函数对象resolve
  133. 返回一个指定结果
  134. */
  135. Promise.resolve = function(value) {
  136. // 返回成功/失败的promise
  137. return new Promise((resolve, reject) => {
  138. if (value instanceof Promise) {
  139. value.then(resolve, reject);
  140. } else {
  141. resolve(value);
  142. }
  143. });
  144. };
  145. /*
  146. Promise函数对象reject
  147. 返回一个失败结果
  148. */
  149. Promise.reject = function(reason) {
  150. return new Promise((resolve, reject) => {
  151. reject(reason);
  152. });
  153. };
  154. /*
  155. Promise函数对象all
  156. 返回一个promise,只有当所有promise都成功时才成功,否则只要有失败就失败
  157. */
  158. Promise.all = function(promises) {
  159. const values = new Array(promises.length); // 用来保存所有成功value的数组
  160. let resolvedCount = 0; // 用来保存成功的promise计数器,每执行成功一次就 ++ ,如果和需要执行的promises的长度相等则能够确定所有的都已经执行成功
  161. return new Promise((resolve, reject) => {
  162. // 遍历获取每一个promise的结果
  163. promises.forEach((p, index) => {
  164. Promise.resolve(p).then(
  165. //使用Promise.resolve(p)是为了解决有可能传入promises数组的不是一个promise而是一个具体的值
  166. // 我们在这个函数中需要明确,如何确保全部都成功,同时返回的成功的promise的顺序不会乱
  167. value => {
  168. resolvedCount++;
  169. // p成功,将成功的value保存到values
  170. values[index] = value;
  171. // 如果全部成功,将return的promise改变成功
  172. if (resolvedCount === promises.length) {
  173. resolve(values);
  174. }
  175. },
  176. // 只要一个失败了,return的promise就会失败
  177. reason => {
  178. reject(reason);
  179. }
  180. );
  181. });
  182. });
  183. };
  184. /*
  185. Promise函数对象race
  186. 返回一个promise,其结果有第一个完成的promise决定
  187. */
  188. Promise.race = function(promises) {
  189. return new Promise((resolve, reject) => {
  190. promises.forEach((p, index) => {
  191. Promise.resolve(p).then(
  192. value => {
  193. resolve(value);
  194. },
  195. reason => {
  196. reject(reason);
  197. }
  198. );
  199. });
  200. });
  201. };
  202. // 向外暴露 Promise 函数
  203. window.Promise = Promise;
  204. })(window);

class版本

  1. /* ---Class版本--- */
  2. /* 自定义promise函数模块
  3. 我们使用es5的方法定义模块,如果使用es6语法这样就需要转义
  4. IIFE - 立即执行函数
  5. */
  6. (function(window) {
  7. const PENDING = "pending";
  8. const RESOLVED = "resolved";
  9. const REJECTED = "rejected";
  10. /*
  11. Promise:构造函数
  12. excutor:执行器(同步执行)
  13. */
  14. class Promise {
  15. constructor(excutor) {
  16. const _this = this;
  17. /*
  18. status:用来存储当前的状态,初始状态是pending
  19. data:给promise对象指定一个用于存储结果数据的属性
  20. callbacks:用于保存{onResolved(){},onRejected(){}}回调
  21. */
  22. _this.status = PENDING;
  23. _this.data = undefined;
  24. _this.callbacks = [];
  25. // 内部定义resolve函数
  26. function resolve(value) {
  27. // 判断当前的状态
  28. if (_this.status !== PENDING) return;
  29. /*
  30. 1.改变状态 pending -> resolved
  31. 2.保存value 将接受的value赋值给data
  32. */
  33. _this.status = RESOLVED;
  34. _this.data = value;
  35. // 如果有待执行的callback函数,立即异步执行回调函数onResolved
  36. if (_this.callbacks.length > 0) {
  37. _this.callbacks.forEach(callbacksObj => {
  38. setTimeout(() => {
  39. //这种写法不太准确,因为setTimeOut属于宏队列元素,但是可以模拟当前需要的异步操作,我们的目的就是将回调函数放入执行stack中异步执行
  40. callbacksObj.onResolved(value);
  41. });
  42. });
  43. }
  44. }
  45. // 内部定义reject函数
  46. function reject(reason) {
  47. /*
  48. 1.改变状态 pending -> rejected
  49. 2.保存reason 将接受的reason赋值给data
  50. */
  51. _this.status = REJECTED;
  52. _this.data = reason;
  53. // 如果有待执行的callback函数,立即异步执行回调函数onRejected
  54. if (_this.callbacks.length > 0) {
  55. _this.callbacks.forEach(callbacksObj => {
  56. setTimeout(() => {
  57. //这种写法不太准确,因为setTimeOut属于宏队列元素,但是可以模拟当前需要的异步操作,我们的目的就是将回调函数放入执行stack中异步执行
  58. callbacksObj.onRejected(reason);
  59. });
  60. });
  61. }
  62. }
  63. // 立即执行excutor
  64. try {
  65. excutor(resolve, reject);
  66. } catch (error) {
  67. // 如果执行器抛出异常,promise对象直接调用rejected
  68. reject(error);
  69. }
  70. }
  71. /*
  72. Promise原型对象的then()
  73. 指定成功和失败的回调函数
  74. 返回一个新的promise对象
  75. 返回的promise的结果有onResolved和onRejected执行结果决定
  76. */
  77. then(onResolved, onRejected) {
  78. const _this = this;
  79. // 指定回调函数的默认值(必须是函数)
  80. onResolved = typeof onResolved === "function" ? onResolved : value => value;
  81. onRejected = typeof onRejected === "function" ? onRejected : reason => { throw reason};
  82. return new Promise((resolve, reject) => {
  83. /*
  84. 执行指定的回调函数,根据执行的结果改变return的promise的状态
  85. */
  86. function handle(callback) {
  87. // 1.抛出异常
  88. try {
  89. const result = callback(_this.data);
  90. if (result instanceof Promise) {
  91. // 2.如果当前返回的是promise
  92. result.then(resolve, reject);
  93. } else {
  94. // 3.如果返回的不是promise,为一个成功值
  95. resolve(result);
  96. }
  97. } catch (error) {
  98. // 4.如果返回的不是promise,为一个异常值
  99. reject(error);
  100. }
  101. }
  102. if (_this.status === RESOLVED) {
  103. // 当前promise是resolved
  104. setTimeout(() => {
  105. handle(onResolved);
  106. });
  107. } else if (_this.status === REJECTED) {
  108. // 当前promise是rejected
  109. setTimeout(() => {
  110. handle(onRejected);
  111. });
  112. } else {
  113. // 当前promise是pending
  114. // 将成功失败的回调函数保存到callbacks中缓存
  115. _this.callbacks.push({
  116. onResolved() {
  117. handle(onResolved);
  118. },
  119. onRejected() {
  120. handle(onRejected);
  121. }
  122. });
  123. }
  124. });
  125. }
  126. /*
  127. Promise的原型对象的catch()
  128. 指定失败的回调函数,返回一个新的promise对象
  129. */
  130. catch(onRejected) {
  131. return this.then(undefined, onRejected);
  132. }
  133. /*
  134. Promise函数对象resolve
  135. 返回一个指定结果
  136. */
  137. static resolve(value) {
  138. // 返回成功/失败的promise
  139. return new Promise((resolve, reject) => {
  140. if (value instanceof Promise) {
  141. value.then(resolve, reject);
  142. } else {
  143. resolve(value);
  144. }
  145. });
  146. }
  147. /*
  148. Promise函数对象reject
  149. 返回一个失败结果
  150. */
  151. static reject(reason) {
  152. return new Promise((resolve, reject) => {
  153. reject(reason);
  154. });
  155. }
  156. /*
  157. Promise函数对象all
  158. 返回一个promise,只有当所有promise都成功时才成功,否则只要有失败就失败
  159. */
  160. static all(promises) {
  161. const values = new Array(promises.length); // 用来保存所有成功value的数组
  162. let resolvedCount = 0; // 用来保存成功的promise计数器,每执行成功一次就 ++ ,如果和需要执行的promises的长度相等则能够确定所有的都已经执行成功
  163. return new Promise((resolve, reject) => {
  164. // 遍历获取每一个promise的结果
  165. promises.forEach((p, index) => {
  166. Promise.resolve(p).then(
  167. //使用Promise.resolve(p)是为了解决有可能传入promises数组的不是一个promise而是一个具体的值
  168. // 我们在这个函数中需要明确,如何确保全部都成功,同时返回的成功的promise的顺序不会乱
  169. value => {
  170. resolvedCount++;
  171. // p成功,将成功的value保存到values
  172. values[index] = value;
  173. // 如果全部成功,将return的promise改变成功
  174. if (resolvedCount === promises.length) {
  175. resolve(values);
  176. }
  177. },
  178. // 只要一个失败了,return的promise就会失败
  179. reason => {
  180. reject(reason);
  181. }
  182. );
  183. });
  184. });
  185. }
  186. /*
  187. Promise函数对象race
  188. 返回一个promise,其结果有第一个完成的promise决定
  189. */
  190. static race(promises) {
  191. return new Promise((resolve, reject) => {
  192. promises.forEach((p, index) => {
  193. Promise.resolve(p).then(
  194. value => {
  195. resolve(value);
  196. },
  197. reason => {
  198. reject(reason);
  199. }
  200. );
  201. });
  202. });
  203. }
  204. }
  205. // 向外暴露 Promise 函数
  206. window.Promise = Promise;
  207. })(window);

其实手写的部分有一定的难度,表现在实现then方法,all方法,实现执行器方法上面

上述的js可以自行测试,满足基本的语法是没有问题的。主要就是为了能够更好的理解promise,如果你能够全部理解掌握promise的知识点,同时动手去撸一个promise。那么你离中高级前端又更近一步啦!