回顾用法

  1. let promise = new Promise((resolve, reject) => {
  2. resolve('成功')
  3. resolve('reject')
  4. })
  5. promise.then(value => {}, reason => {})
  1. Promise就是一个类 在执行这个类的时候,需要传递一个执行器进去 执行器会立即执行
  2. Promise 有三种状态 分别为成功 fulfilled、 失败 rejected、 等待 pending
    • 一旦状态确定就不可更改
    • pending -> fulfilled
    • pending -> rejected
  3. resolve 和 rejected 函数是用来更改状态的
    • resolve : fulfilled
    • reject : rejected
  4. then方法内部做的事情就判断状态 如果状态是成功 调用成功的回调函数 如果状态是失败 调用失败回调函数 then方法是被定义在原型对象中的
  5. then成功回调有一个参数 表示成功之后的值 then失败回调有一个参数 表示失败后的原因

核心逻辑

定义状态枚举

  • 把三个状态定义为枚举。 便于以后的非字符串输入引起错误

    1. const PENDING = "pending";
    2. const RESOLVED = "resolved";
    3. const REJECTED = "rejected";

    定义一个类

  • 在回顾用法中知道,new promise 过程中会传入

    1. class MyPromise {
    2. constructor(executor) {
    3. executor(this.resolve, this.reject);
    4. }
    5. }

    状态更改

  • 状态只允许更改一次。,要做非等待状态的判断

  • 修改对应的状态 ```javascript class MyPromise { constructor(executor) { executor(this.resolve, this.reject); } status = PENDING;

    resolve = () => { // 状态只允许更改一次。 if (this.status !== PENDING) return; // 将状态更改为成功 this.status = RESOLVED; };

    reject = () => { if (this.status !== PENDING) return; // 将状态更改为失败 this.status = REJECTED; }; }

  1. <a name="IQyoh"></a>
  2. ### then
  3. - 会有成功 、 失败的回调
  4. - 回调会有原因, 因此在改变状态的时候需要保存原因,在回调的时候返回
  5. ```javascript
  6. class MyPromise {
  7. constructor(executor) {
  8. executor(this.resolve, this.reject);
  9. }
  10. status = PENDING;
  11. value = undefined
  12. reason = undefined
  13. resolve = value => {
  14. if (this.status !== PENDING) return;
  15. this.status = RESOLVED;
  16. // 1 保存成功原因
  17. this.value = value
  18. };
  19. reject = reason => {
  20. if (this.status !== PENDING) return;
  21. this.status = REJECTED;
  22. // 1 保存失败原因
  23. this.reason = reason
  24. };
  25. then(successCallback, failCallback) {
  26. // 2 判断状态
  27. if(this.status === RESOLVED) {
  28. successCallback(this.value)
  29. } else if(this.status === REJECTED){
  30. failCallback(this.reason)
  31. }
  32. }
  33. }

异步逻辑

  1. eg: 异步回调。
  1. let promise = new Promise((resolve, reject) => {
  2. setTimeout(() => {
  3. resolve("成功");
  4. reject('失败')
  5. }, 20000)
  6. });
  7. promise.then(
  8. (value) => {
  9. console.log("----value", value);
  10. },
  11. (reason) => {
  12. console.log("----reason", reason);
  13. }
  14. );

此时按照目前的逻辑,是不会执行 successCallbackfailCallback

改造:

  • then 中判断是否是 等待状态 ,如果是,保存 成功和失败 的callback
  • 在resolve 、reject中判断 这个回调是否存在,存在并把对应参数带回去调用。

    1. class MyPromise {
    2. constructor(executor) {
    3. executor(this.resolve, this.reject);
    4. }
    5. status = PENDING;
    6. value = undefined;
    7. reason = undefined;
    8. // 1 定义两个callback变量
    9. successCallback = undefined;
    10. failCallback = undefined;
    11. resolve = (value) => {
    12. if (this.status !== PENDING) return;
    13. this.status = RESOLVED;
    14. this.value = value;
    15. // 2 如果有callback则调用,并把对应参数带过去
    16. this.successCallback && this.successCallback(this.value)
    17. };
    18. reject = (reason) => {
    19. if (this.status !== PENDING) return;
    20. this.status = REJECTED;
    21. this.reason = reason;
    22. // 2 如果有callback则调用,并把对应参数带过去
    23. this.failCallback && this.failCallback(this.reason)
    24. };
    25. then(successCallback, failCallback) {
    26. if (this.status === RESOLVED) {
    27. successCallback(this.value);
    28. } else if (this.status === REJECTED) {
    29. failCallback(this.reason);
    30. } else {
    31. // 3 如果还是等待状态,保存callback
    32. this.successCallback = successCallback;
    33. this.failCallback = failCallback;
    34. }
    35. }
    36. }

    then 方法多次调用添加多个处理函数

    同一个promise对象下面的then方法是可以被调用多次的。
    eg: ```javascript let promise = new MyPromise((resolve, reject) => { setTimeout(() => { resolve(“成功”); reject(“失败”); }, 2000); // resolve(“成功”); // reject(“失败”); }); promise.then( (value) => { console.log(“——value”, value); }, (reason) => { console.log(“——reason”, reason); } );

promise.then((value) => { console.log(1, value); }); promise.then((value) => { console.log(2, value); }); promise.then((value) => { console.log(3, value); });

  1. 那么在此时,目前的代码只会保存最后一次的 `callback`, 因此我们需要
  2. - `callback` 改造成数组
  3. ```javascript
  4. class MyPromise {
  5. constructor(executor) {
  6. executor(this.resolve, this.reject);
  7. }
  8. status = PENDING;
  9. value = undefined;
  10. reason = undefined;
  11. // 1 变成数组
  12. successCallback = [];
  13. failCallback = []
  14. resolve = (value) => {
  15. if (this.status !== PENDING) return;
  16. this.status = RESOLVED;
  17. this.value = value;
  18. // 2 while 判断长度,shift 不断推出第一个元素,将this.value传进去
  19. while(this.successCallback.length) this.successCallback.shift()(this.value)
  20. };
  21. reject = (reason) => {
  22. if (this.status !== PENDING) return;
  23. this.status = REJECTED;
  24. this.reason = reason;
  25. // 2 while 判断长度,shift 不断推出第一个元素,将this.value传进去
  26. while(this.failCallback.length) this.failCallback.shift()(this.reason)
  27. };
  28. then(successCallback, failCallback) {
  29. if (this.status === RESOLVED) {
  30. successCallback(this.value);
  31. } else if (this.status === REJECTED) {
  32. failCallback(this.reason);
  33. } else {
  34. // 3 变成push
  35. this.successCallback.push(successCallback);
  36. this.failCallback.push(failCallback);
  37. }
  38. }
  39. }

链式调用

then方法是可以被链式调用的, 后面then方法的回调函数拿到值的是上一个then方法的回调函数的返回值

普通值

  1. let promise = new Promise((resolve, reject) => {
  2. resolve("成功");
  3. });
  4. promise.then((value) => {
  5. console.log(1, value);
  6. return 100
  7. }).then(value => {
  8. console.log(value);
  9. })

输出结果如下
image.png
因此我们需要

  • 返回新的 promise
  • successCallback 返回的东西也需要带给下一个 .then
  • 以前then 需要立即执行,放哪? -> 放入 new Promise 中,立即执行

    1. then(successCallback, failCallback) {
    2. // 定义为一个新的Promise
    3. let promise2 = new MyPromise((resolve, reject) => {
    4. if (this.status === RESOLVED) {
    5. // 将当前successCallback return 的值返回
    6. let x = successCallback(this.value);
    7. resolve(x)
    8. } else if (this.status === REJECTED) {
    9. failCallback(this.reason);
    10. } else {
    11. this.successCallback.push(successCallback);
    12. this.failCallback.push(failCallback);
    13. }
    14. });
    15. // 将新的Promise返回,以完成链式调用
    16. return promise2;
    17. }

    callback 返回的又是一个Promise

    特俗的, 如果返回的又是一个Promise, 那么我们需要判断,Promise的状态是成功 的还是失败的,如果是成功,则调用resolve, 如果是 失败,则要 reject
    需要处理逻辑的如下

  • 判断 x 的值是普通值还是promise对象

  • 如果是普通值 直接调用resolve
  • 如果是promise对象 查看promsie对象返回的结果
  • 再根据promise对象返回的结果 决定调用resolve 还是调用reject

我们定义一个新方法resolvePromise(不是类中的方法,定义在类之外),便于统一调用。 传递的参数分别是 callback的值resolvereject

  1. function resolvePromise (x, resolve, reject) {
  2. //判断 x 的值是否 promise 对象
  3. if (x instanceof MyPromise) {
  4. x.then(resolve, reject);
  5. } else {
  6. // 普通值
  7. resolve(x);
  8. }
  9. }

then 中修改如下

  1. then(successCallback, failCallback) {
  2. let promise2 = new MyPromise((resolve, reject) => {
  3. if (this.status === RESOLVED) {
  4. let x = successCallback(this.value);
  5. // 调用resolvePromise
  6. resolvePromise(x, resolve, reject)
  7. } else if (this.status === REJECTED) {
  8. failCallback(this.reason);
  9. } else {
  10. this.successCallback.push(successCallback);
  11. this.failCallback.push(failCallback);
  12. }
  13. });
  14. return promise2;
  15. }

特殊循环调用

在特殊情况下,可以让return的promise 为自身,这就会导致循环调用。
eg:

  1. let promise = new Promise((resolve, reject) => {
  2. resolve("成功");
  3. });
  4. let promise2 = promise
  5. .then((value) => {
  6. console.log(1, value);
  7. return promise2;
  8. })

结果如下
image.png
因此我们需要判断 return 的内容是否为 自身。
修改如下

  1. class MyPromise {
  2. ....
  3. then(successCallback, failCallback) {
  4. let promise2 = new MyPromise((resolve, reject) => {
  5. if (this.status === RESOLVED) {
  6. let x = successCallback(this.value);
  7. // 将promise2 自身传进去做判断
  8. resolvePromise(promise2, x, resolve, reject)
  9. } else if (this.status === REJECTED) {
  10. failCallback(this.reason);
  11. } else {
  12. this.successCallback.push(successCallback);
  13. this.failCallback.push(failCallback);
  14. }
  15. });
  16. return promise2;
  17. }
  18. }
  19. function resolvePromise (promise2, x, resolve, reject) {
  20. // 加上判断是否为自身, 如果是reject一个错误。
  21. if(promise2 === x) {
  22. return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
  23. }
  24. if (x instanceof MyPromise) {
  25. x.then(resolve, reject);
  26. } else {
  27. resolve(x);
  28. }
  29. }

但这由有一个新的问题,在resolvePromise传值的时候,promise 是还没有拿到的。 我们需要怎么做呢

  • 处理成异步

因此我们只要加个settime即可。

  1. class MyPromise {
  2. 。。。
  3. then(successCallback, failCallback) {
  4. let promise2 = new MyPromise((resolve, reject) => {
  5. if (this.status === RESOLVED) {
  6. // 添加setTimeout, 使其异步化
  7. setTimeout(() => {
  8. let x = successCallback(this.value);
  9. resolvePromise(promise2, x, resolve, reject);
  10. }, 0);
  11. } else if (this.status === REJECTED) {
  12. failCallback(this.reason);
  13. } else {
  14. this.successCallback.push(successCallback);
  15. this.failCallback.push(failCallback);
  16. }
  17. });
  18. return promise2;
  19. }
  20. }

捕获错误

截至至目前,我们都在处理正常的情况,我们需要添加相应的错误兼容,已保证代码的正常执行。

  • 添加try catch

    1. class MyPromise {
    2. constructor(executor) {
    3. // 添加try catch
    4. try {
    5. executor(this.resolve, this.reject);
    6. } catch (error) {
    7. // 将错误reject 出去
    8. this.reject(error)
    9. }
    10. }
    11. ....
    12. then(successCallback, failCallback) {
    13. let promise2 = new MyPromise((resolve, reject) => {
    14. if (this.status === RESOLVED) {
    15. setTimeout(() => {
    16. // 添加try catch
    17. try {
    18. let x = successCallback(this.value);
    19. resolvePromise(promise2, x, resolve, reject);
    20. } catch (error) {
    21. reject(error)
    22. }
    23. }, 0);
    24. } else if (this.status === REJECTED) {
    25. failCallback(this.reason);
    26. } else {
    27. this.successCallback.push(successCallback);
    28. this.failCallback.push(failCallback);
    29. }
    30. });
    31. return promise2;
    32. }
    33. }

    补充其他状态的处理

    目前,我们只是处理的resolve 的状态,我们继续添加reject 状态的代码

    1. class MyPromise {
    2. ...
    3. then(successCallback, failCallback) {
    4. let promise2 = new MyPromise((resolve, reject) => {
    5. if (this.status === RESOLVED) {
    6. setTimeout(() => {
    7. try {
    8. let x = successCallback(this.value);
    9. resolvePromise(promise2, x, resolve, reject);
    10. } catch (error) {
    11. reject(error)
    12. }
    13. }, 0);
    14. } else if (this.status === REJECTED) {
    15. setTimeout(() => {
    16. // 添加 try catch
    17. try {
    18. let x = failCallback(this.reason)
    19. resolvePromise(promise2, x, resolve, reject);
    20. } catch (error) {
    21. reject(error)
    22. }
    23. }, 0);
    24. } else {
    25. this.successCallback.push(successCallback);
    26. this.failCallback.push(failCallback);
    27. }
    28. });
    29. return promise2;
    30. }
    31. }

    异步处理

    结合前面成功 和 失败的 处理, 我们还需要对异步的回调函数处理

    1. class MyPromise {
    2. constructor(executor) {
    3. try {
    4. executor(this.resolve, this.reject);
    5. } catch (error) {
    6. this.reject(error)
    7. }
    8. }
    9. status = PENDING;
    10. value = undefined;
    11. reason = undefined;
    12. successCallback = [];
    13. failCallback = [];
    14. resolve = (value) => {
    15. if (this.status !== PENDING) return;
    16. this.status = RESOLVED;
    17. this.value = value;
    18. // 不再需要传值
    19. // while (this.successCallback.length) this.successCallback.shift()(this.value);
    20. while (this.successCallback.length) this.successCallback.shift()();
    21. };
    22. reject = (reason) => {
    23. if (this.status !== PENDING) return;
    24. this.status = REJECTED;
    25. this.reason = reason;
    26. // 不再需要传值
    27. // while (this.failCallback.length) this.failCallback.shift()(this.reason);
    28. while (this.failCallback.length) this.failCallback.shift()();
    29. };
    30. then(successCallback, failCallback) {
    31. let promise2 = new MyPromise((resolve, reject) => {
    32. if (this.status === RESOLVED) {
    33. setTimeout(() => {
    34. try {
    35. let x = successCallback(this.value);
    36. resolvePromise(promise2, x, resolve, reject);
    37. } catch (error) {
    38. reject(error)
    39. }
    40. }, 0);
    41. } else if (this.status === REJECTED) {
    42. setTimeout(() => {
    43. try {
    44. let x = failCallback(this.reason)
    45. resolvePromise(promise2, x, resolve, reject);
    46. } catch (error) {
    47. reject(error)
    48. }
    49. }, 0);
    50. } else {
    51. this.successCallback.push(() => {
    52. // 将成功的函数copy一份放在此
    53. setTimeout(() => {
    54. try {
    55. let x = successCallback(this.value);
    56. resolvePromise(promise2, x, resolve, reject);
    57. } catch (error) {
    58. reject(error)
    59. }
    60. }, 0);
    61. });
    62. this.failCallback.push(() => {
    63. // 将失败的函数copy一份放在此
    64. setTimeout(() => {
    65. try {
    66. let x = failCallback(this.reason)
    67. resolvePromise(promise2, x, resolve, reject);
    68. } catch (error) {
    69. reject(error)
    70. }
    71. }, 0);
    72. });
    73. }
    74. });
    75. return promise2;
    76. }
    77. }

    将 then 方法的参数变成可选参数

    我们先来看一段代码 ```javascript let promise = new Promise((resolve, reject) => { resolve(“成功”); // reject(“失败”); });

promise .then() .then() .then((value) => { console.log(value); });

  1. `then` 中,我们可以选择不传递参数,在最后有参数的地方,拿到一层层传递下来的参数。<br />实际上,上面的代码 等同于 下面的代码
  2. ```javascript
  3. promise
  4. .then(value => value)
  5. .then(value => value)
  6. .then((value) => {
  7. console.log(value);
  8. });

因此

  • 判断是否有callback, 有则用,没有则补充

    1. class MyPromise {
    2. ...
    3. then(successCallback, failCallback) {
    4. // 添加可选参数
    5. successCallback = successCallback || (value => value);
    6. // 失败的回调需加 throw
    7. failCallback = failCallback || (reason => { throw reason });
    8. let promise2 = new MyPromise((resolve, reject) => {
    9. ...
    10. }
    11. return promise2;
    12. }
    13. }

    静态方法

    all

    Promise 允许我们将多个promise 执行完后一次性返回, 这就是 all 方法。注意的是,这是个静态方法。以下代码是例子。 特殊的,有一个返回的是 reject, 则其他都不会返回 ```javascript let p1 = new Promise((resolve, reject) => { setTimeout(() => { resolve(“成功 p1”); }, 2000) });

let p2 = new Promise((resolve, reject) => { resolve(“成功 p2”); });

let p = Promise.all([‘a1’, ‘a2’, p1, p2, ‘c1’]) p.then(res => console.log(res))

  1. 由以上代码可以得知,
  2. - `all` 传递的是个数组
  3. - 传递元素可以是非promise实例
  4. 实现代码
  5. ```javascript
  6. class MyPromise {
  7. ...
  8. // 定义静态方法all
  9. static all(arr) {
  10. // 定义一个数组保存结果
  11. let result = [];
  12. // 保存一个index 和 数组长度判断是否执行
  13. let index = 0;
  14. return new MyPromise((resolve, reject) => {
  15. function addData(key, value) {
  16. // 保存结果值
  17. result[key] = value;
  18. // 每次+1
  19. index++;
  20. // 判断是否执行
  21. if (index === arr.length) {
  22. resolve(result);
  23. }
  24. }
  25. for (let idx = 0; idx < arr.length; idx++) {
  26. const current = arr[idx];
  27. // 判断是否是MyPromise 实例下的
  28. if (current instanceof MyPromise) {
  29. // 将then 中的结果放入 结果数组
  30. current.then(
  31. (value) => addData(idx, value),
  32. (reason) => reject(reason)
  33. );
  34. } else {
  35. // 如果不是直接add进结果数组
  36. addData(idx, current);
  37. }
  38. }
  39. });
  40. }
  41. }

resolve

resolve 可以将传进来的参数变成一个promise. 让后续也可以链式调用。 例子如下

  1. function p1() {
  2. return new Promise((resolve, reject) => {
  3. setTimeout(() => {
  4. resolve("成功 p1");
  5. }, 2000);
  6. });
  7. }
  8. Promise.resolve(10).then((res) => console.log(res));
  9. Promise.resolve(p1()).then((res) => console.log(res));

log如下
image.png
其实很简单。

  • 判断是否是 Promise实例,如果是直接 返回
  • 不是 resolve出去

    1. class MyPromise {
    2. ...
    3. // 定义静态方法resolve
    4. static resolve (value) {
    5. // 如果是Promise实例,直接返回
    6. if (value instanceof MyPromise) return value;
    7. // 不是则resolve 出去
    8. return new MyPromise(resolve => resolve(value));
    9. }
    10. }

    finally

    我们知道 finally, 无论如何都可以调用 。我们先来复习看下例子是如何用的

  1. let p1 = new Promise((resolve, reject) => {
  2. console.log('.....');
  3. resolve("成功 p1");
  4. });
  5. p1.then((res) => console.log(res)).finally(() => {
  6. console.log("----1");
  7. });
  8. p1.finally(() => {
  9. console.log("----2");
  10. }).then((res) => console.log(res))

log 如下
image.png
我们可以发现

  • finally 可以放在如何位置 按顺序执行
  • finally 放前面 后面接 then 是可以拿到 返回的值
  • 需要注意的是,这里有微任务宏任务的概念。 then 后面接 finally 或者 finally 后面接then 都是第二次微任务。
  • 需要考虑finally 在前面,返回的value 是异步的情况。

代码如下

  1. class MyPromise {
  2. ...
  3. finally(callback) {
  4. // 因为可以链式调用,我们需要返回一个promise, 直接调用.then 方法既可。
  5. return this.then(value => {
  6. // 如果 return 的是个promise 需要等待执行完再return
  7. return MyPromise.resolve(callback()).then(() => value)
  8. }, reason => {
  9. return MyPromise.resolve(callback()).then(() => { throw reason })
  10. })
  11. }
  12. }

catch

话不多说,先看例子

  1. let p1 = new Promise((resolve, reject) => {
  2. reject('失败回调')
  3. });
  4. p1.then((res) => console.log(res))
  5. .catch(err => {
  6. console.log(err);
  7. })

log 如下;
image.png
我们可以发现

  • then不传递 失败回调时,是可以在 catch 中捕获到的。

其实实现很简单,只需要将callback放入then(undefind, callback ) 既可
代码实现如下

  1. class MyPromise {
  2. ...
  3. catch (failCallback) {
  4. return this.then(undefined, failCallback)
  5. }
  6. }

结束

自此,已完成全部逻辑。下面是代码总览

  1. const PENDING = 'pending'; // 等待
  2. const FULFILLED = 'fulfilled'; // 成功
  3. const REJECTED = 'rejected'; // 失败
  4. class MyPromise {
  5. constructor (executor) {
  6. try {
  7. executor(this.resolve, this.reject)
  8. } catch (e) {
  9. this.reject(e);
  10. }
  11. }
  12. // promsie 状态
  13. status = PENDING;
  14. // 成功之后的值
  15. value = undefined;
  16. // 失败后的原因
  17. reason = undefined;
  18. // 成功回调
  19. successCallback = [];
  20. // 失败回调
  21. failCallback = [];
  22. resolve = value => {
  23. // 如果状态不是等待 阻止程序向下执行
  24. if (this.status !== PENDING) return;
  25. // 将状态更改为成功
  26. this.status = FULFILLED;
  27. // 保存成功之后的值
  28. this.value = value;
  29. // 判断成功回调是否存在 如果存在 调用
  30. while(this.successCallback.length) this.successCallback.shift()()
  31. }
  32. reject = reason => {
  33. // 如果状态不是等待 阻止程序向下执行
  34. if (this.status !== PENDING) return;
  35. // 将状态更改为失败
  36. this.status = REJECTED;
  37. // 保存失败后的原因
  38. this.reason = reason;
  39. // 判断失败回调是否存在 如果存在 调用
  40. while(this.failCallback.length) this.failCallback.shift()()
  41. }
  42. then (successCallback, failCallback) {
  43. // 添加可选参数
  44. successCallback = successCallback || (value => value);
  45. // 失败的回调需加 throw
  46. failCallback = failCallback || (reason => { throw reason });
  47. let promsie2 = new MyPromise((resolve, reject) => {
  48. // 判断状态
  49. if (this.status === FULFILLED) {
  50. setTimeout(() => {
  51. // 添加容错
  52. try {
  53. let x = successCallback(this.value);
  54. resolvePromise(promsie2, x, resolve, reject)
  55. }catch (e) {
  56. reject(e);
  57. }
  58. }, 0)
  59. }else if (this.status === REJECTED) {
  60. setTimeout(() => {
  61. // 添加容错
  62. try {
  63. let x = failCallback(this.reason);
  64. resolvePromise(promsie2, x, resolve, reject)
  65. }catch (e) {
  66. reject(e);
  67. }
  68. }, 0)
  69. } else {
  70. // 等待
  71. // 将成功回调和失败回调存储起来
  72. this.successCallback.push(() => {
  73. setTimeout(() => {
  74. try {
  75. let x = successCallback(this.value);
  76. resolvePromise(promsie2, x, resolve, reject)
  77. }catch (e) {
  78. reject(e);
  79. }
  80. }, 0)
  81. });
  82. this.failCallback.push(() => {
  83. setTimeout(() => {
  84. try {
  85. let x = failCallback(this.reason);
  86. resolvePromise(promsie2, x, resolve, reject)
  87. }catch (e) {
  88. reject(e);
  89. }
  90. }, 0)
  91. });
  92. }
  93. });
  94. return promsie2;
  95. }
  96. finally(callback) {
  97. // 因为可以链式调用,我们需要返回一个promise, 直接调用.then 方法既可。
  98. return this.then(value => {
  99. // 如果 return 的是个promise 需要等待执行完再return
  100. return MyPromise.resolve(callback()).then(() => value)
  101. }, reason => {
  102. return MyPromise.resolve(callback()).then(() => { throw reason })
  103. })
  104. }
  105. catch (failCallback) {
  106. return this.then(undefined, failCallback)
  107. }
  108. // 定义静态方法all
  109. static all(arr) {
  110. // 定义一个数组保存结果
  111. let result = [];
  112. // 保存一个index 和 数组长度判断是否执行
  113. let index = 0;
  114. return new MyPromise((resolve, reject) => {
  115. function addData(key, value) {
  116. // 保存结果值
  117. result[key] = value;
  118. // 每次+1
  119. index++;
  120. // 判断是否执行
  121. if (index === arr.length) {
  122. resolve(result);
  123. }
  124. }
  125. for (let idx = 0; idx < arr.length; idx++) {
  126. const current = arr[idx];
  127. // 判断是否是MyPromise 实例下的
  128. if (current instanceof MyPromise) {
  129. // 将then 中的结果放入 结果数组
  130. current.then(
  131. (value) => addData(idx, value),
  132. (reason) => reject(reason)
  133. );
  134. } else {
  135. // 如果不是直接add进结果数组
  136. addData(idx, current);
  137. }
  138. }
  139. });
  140. }
  141. // 定义静态方法resolve
  142. static resolve (value) {
  143. // 如果是Promise实例,直接返回
  144. if (value instanceof MyPromise) return value;
  145. // 不是则resolve 出去
  146. return new MyPromise(resolve => resolve(value));
  147. }
  148. }
  149. // 判断 x 的值是普通值还是promise对象
  150. // 如果是普通值 直接调用resolve
  151. // 如果是promise对象 查看promsie对象返回的结果
  152. // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
  153. function resolvePromise (promsie2, x, resolve, reject) {
  154. if (promsie2 === x) {
  155. return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
  156. }
  157. if (x instanceof MyPromise) {
  158. // promise 对象
  159. // x.then(value => resolve(value), reason => reject(reason));
  160. x.then(resolve, reject);
  161. } else {
  162. // 普通值
  163. resolve(x);
  164. }
  165. }