1、 promise是个构造函数;
    promise的构造函数内部要声明一个表示状态的属性state(默认pending)和结果result;
    promise支持异步调用,设置一个callbacks保存回调函数,且支持链式调用所以数据类型为数组;
    接收的参数是个函数(有resolve和reject两个参数),在构造函数中定义resolve和reject两个方法
    2、 构造函数中的resolve方法,promise的状态改变只有一次,所以state不是pending直接return;
    之后state改为fulfilled并为result赋值(resolve的行参data);
    执行回调函数,因为promise的链式调用,遍历执行callbacks中接收的onResolve方法;
    3、 reject方法与resolve类似,判断pending—>修改state为reject—>给result赋值—>遍历执行回调
    4、 执行构造函数传入的参数函数(executor),把resolve和reject方法传入, executor(resolve, reject)
    promise的状态可以被throw方法改变,所以使用try catch执行,try executor catch则reject();
    5、 promise实例有then和catch方法,所以写在promise的prototype上;
    catch相当于then方法不传第一个参数,所以catch可以直接返回promise.then(undefined, onRejected)
    6、 then方法的处理,then要写在原型上;
    then接收两个函数作为参数,onResolve和onReject,注意空值处理,没传参数或类型不是function是给默认方法,onResolve默认将value向下传递(链式调用),onReject默认throw reason
    then返回的是promise对象,所以return new promise
    在返回的promise对象中处理各种逻辑,实例的state为fulfill时调用onResolved,reject时调用onRejected,pending时向callbacks数组中push存有两个回调函数的对象为promise构造函数中执行时遍历回调使用
    then返回的是一个promise对象,默认resolve状态,且promise有错误穿透所以对onResolved和onRejected都进行try catch执行,并判断执行结果是否为promise实例,是则resolve,否则reject;
    上述对onResolved和onRejected的处理可以进行封装,封装成一个callback方法。接收参数为要执行的方法;
    7、 注意then中的回调函数是异步执行的 所以使用setTimeout包裹resolve和reject方法,promise构造函数中的callbacks回调事件数组同理
    8、 实现promise的其它方法resolve、reject、all、race;按照特性写就ok;方法不在实例上调用所以写在promise函数上而不是promise原型上
    resolve return一个promise对象,传入普通类型 return 结果为resolve,传入promise return的结果与传入的promise运行结果一致
    reject 返回一个promise对象 无论如何都是reject
    all 接收一个promise数组,所有resolve返回resolve,结果为数组,遍历调用传入的数组的每一个promise对象的then方法,resolve则计数+存结果,知道数和传入的数组长度相等 resolve(arr),reject则reject(r);
    race 返回第一个执行完毕的,所以return一个promise对象 遍历执行传入数组的promise对象的then方法,resolve便resolve(); reject则reject();
    9、 写完之后可以选择使用class封装Promise,声明一个class ,constructor为构造函数,然后有then和catch方法,将resolve reject all race等方法写成静态属性 前面加static

    1. // 声明结构 promise 是个构造函数,接收一个函数做为参数
    2. function _Promise (executor) {
    3. // 声明返回状态和返回结果
    4. this.PromiseState = 'pending'; // 默认pending状态
    5. this.PromiseResult = null;
    6. this.callbacks = []; // 保存回调函数,promise可以多次回调 所以选择使用数组
    7. const _this = this; // 为了在函数中使用this
    8. // 声明resolve 和 reject函数, 接收data作为返回结果
    9. function resolve (data) {
    10. // resolve和reject只能执行一次,状态只能改变一次,不是pending状态便返回
    11. if (_this.PromiseState !== 'pending') {
    12. return;
    13. }
    14. _this.PromiseState = 'fulfilled'; // 修改状态为resolve
    15. _this.PromiseResult = data; // 返回结果
    16. setTimeout(() => { // 使用setTimeout 异步执行回调函数 reject同理
    17. _this.callbacks.forEach(item => { // 遍历回调数组,传入data
    18. item.onResolved(data)
    19. })
    20. });
    21. }
    22. function reject (data) { // 同上
    23. if (_this.PromiseState !== 'pending') {
    24. return;
    25. }
    26. _this.PromiseState = 'reject';
    27. _this.PromiseResult = data;
    28. setTimeout(() => {
    29. _this.callbacks.forEach(item => {
    30. item.onRejected(data)
    31. })
    32. });
    33. }
    34. try { // 使用try catch 来解决使用throw 改变promise状态
    35. executor(resolve, reject); // 执行executor 传入 resolve 和 reject 函数
    36. } catch (err) {
    37. reject(err);
    38. }
    39. }
    40. // promise原型上声明.then方法
    41. _Promise.prototype.then = function (onResolved, onRejected) {
    42. if (typeof onRejected !== 'function') { // then的第二个参数没传 给个默认值 抛出reason
    43. onRejected = reason => {
    44. throw reason; // 使用throw 完成catch穿透,链式调用中可以使用一个catch捕获到前面多个then的reject
    45. }
    46. }
    47. if (typeof onResolved !== 'function') { // then的第一参数没传,给onResolve设置一个默认值
    48. onResolved = value => value; // 接收一个value return 一个value 链式调用中就可以继续向后传值运行
    49. }
    50. return new _Promise((resolve, reject) => { // .then返回的是一个promise对象 见下面callback函数
    51. const _this = this; // 封装callback 在callback内可以访问到Promise实例
    52. // 封装then的调用函数,传入resolve和reject处理函数,try catch捕获throw
    53. // 在then的执行结果也会返回一个promise对象,如果return普通值便是resolve状态+return结果,
    54. function callback (fn) {
    55. try { // 避免回调也抛出错误
    56. let result = fn(_this.PromiseResult); // PromiseResult便是resolve时的参数
    57. if (result instanceof _Promise) { // 如果调用.then (即onResolved)返回的是一个promise
    58. result.then(v => { // 返回一个promise对象时
    59. resolve(v);
    60. }, r => {
    61. reject(r);
    62. });
    63. } else { // 如果return正常数据 调用resolve 传入 result
    64. resolve(result);
    65. }
    66. } catch (err) { // 捕获错误 在then中throw也能reject
    67. reject(err);
    68. }
    69. }
    70. // 执行.then,this指向的也是promise实例
    71. if (this.PromiseState === 'fulfilled') { //不同PromiseState执行不同回调
    72. setTimeout(() => { // 使用settimeout使then的回调函数异步执行 reject同理
    73. callback(onResolved);
    74. });
    75. }
    76. if (this.PromiseState === 'reject') {
    77. setTimeout(() => { // 使用settimeout使then的回调函数异步执行
    78. callback(onRejected);
    79. });
    80. }
    81. if (this.PromiseState === 'pending') { // 处理异步任务时 保存回调函数
    82. this.callbacks.push({ // callbacks回调数组,会在异步调用时在promise中调用
    83. onResolved: callback(onResolved),
    84. onRejected: callback(onRejected)
    85. })
    86. }
    87. })
    88. }
    89. // 添加catch方法 直接在调用then就行,onResolve传undefined
    90. _Promise.prototype.catch = function (onRejected) {
    91. return this.then(undefined, onRejected);
    92. }
    93. // resolve传入普通类型 必定返回成功,传入promise对象 返回状态等于传入的执行结果状态
    94. // 添加resolve方法,resolve方法是在Promise上调用的,不是在实例上调用的 所以不要写在原型上
    95. _Promise.resolve = function (value) {
    96. return new _Promise((resolve, reject) => { // resolve返回一个promise对象
    97. // 如果传入的是一个promise对象 那么resolve返回的就是 传入value的执行结果
    98. if (value instanceof _Promise) {
    99. value.then(v => {
    100. resolve(v);
    101. }, r => {
    102. reject(r);
    103. })
    104. } else { // 传入的不是promise 返回的是状态成功 resolve
    105. resolve(value);
    106. }
    107. })
    108. }
    109. // 添加reject方法 reject无论传入什么都是reject状态
    110. _Promise.reject = function (reason) {
    111. return new _Promise((resolve, reject) => { // 返回一个promise对象
    112. reject(reason); // 无论如何都是reject
    113. })
    114. }
    115. // 添加all方法, promise.all 接收一个promise的数组,
    116. // 全部resolve返回状态变为resolve返回结果为数组中所有promise的返回结果的数组,
    117. // 有一个不成功的便返回reject和当前失败的结果
    118. _Promise.all = function (promises) {
    119. let count = 0; // promises中执行成功的计数
    120. let arr = []; // 成功结果的数组
    121. return new _Promise((resolve, reject) => { // 返回的是一个promise对象
    122. for (let i in promises) { // 遍历传入的promise数组
    123. promises[i].then(v => { // 传入的都是promise对象 所以必然有then方法
    124. count++; // 状态为resolve 计数+1
    125. arr[i] = v; // 将结果存到数组,push也行 但保证返回结果和传入promise的顺序一致,使用下标赋值
    126. // 如果计数和传入数组长度相等,说明全部resolve 执行resolve
    127. if (count === promises.length) {
    128. resolve(arr);
    129. }
    130. }, r => { // 有一次reject 执行reject将结果返回
    131. reject(r);
    132. })
    133. }
    134. })
    135. }
    136. // 添加race方法,race也是接收一个promise的数组,返回状态和结果等于最先执行完的promise的状态和结果
    137. _Promise.race = function (promises) {
    138. return new _Promise((resolve, reject) => {
    139. for (let i in promises) {
    140. promises[i].then(v => {
    141. resolve(v);
    142. }, r => {
    143. reject(r);
    144. })
    145. }
    146. })
    147. }
    148. // 使用class写promise 把构造函数放在class的constructor中 then和catch直接写在class里
    149. // resolve、reject、all、race等方法写作静态属性 前面加static