前言

Promisejs 异步编程的核心概念之一,它为我们提供了一种更优雅的方式来处理异步操作。

本文将全面剖析 Promise 的工作原理,并逐步实现一个符合 Promise/A+ 规范的 Promise 库

正文

一、Promise 基础概念

Promise 代表一个异步操作的最终完成(或失败)及其结果值。它有种状态:

  1. pending初始状态,既不是成功,也不是失败状态
  2. fulfilled:意味着操作成功完成
  3. rejected:意味着操作失败

状态一旦改变就不能再变,只能从 pending 变为 fulfilled ,或从 pending 变为 rejected

二、Promise 核心静态方法实现

1. Promise.resolve 实现

Promise.resolve 方法返回一个以给定值解析后的 Promise 对象

 1Promise.resolve = (param) => {
 2  if(param instanceof Promise) return param;
 3  return new Promise((resolve, reject) => {
 4    if(param && param.then && typeof param.then === 'function') {
 5      
 6      param.then(resolve, reject);
 7    }else {
 8      resolve(param);
 9    }
10  })
11}

实现要点:

  • 如果参数Promise 实例,直接返回该实例
  • 如果参数是 thenable 对象(具有 then 方法的对象),返回的 Promise 会跟随这个对象`
  • 其他情况返回一个以该值为成功状态的 Promise 对象

2. Promise.reject 实现

Promise.reject 方法返回一个带有拒绝原因Promise 对象

 1Promise.reject = function (reason) {
 2    return new Promise((resolve, reject) => {
 3        reject(reason);
 4    });
 5}

与 resolve 不同,reject 会原封不动地将 reason 向下传递

三、Promise 实例方法实现

1. Promise.prototype.finally 实现

finally 方法无论 Promise 最终状态如何都会执行。

 1Promise.prototype.finally = function(callback) {
 2  this.then(value => {
 3    return Promise.resolve(callback()).then(() => {
 4      return value;
 5    })
 6  }, error => {
 7    return Promise.resolve(callback()).then(() => {
 8      throw error;
 9    })
10  })
11}

实现要点:

  • 无论成功或失败都会执行回调
  • 保持原 Promise下传
  • 回调函数返回的 Promise 会等待执行完毕

2. Promise.prototype.then 实现

then 方法是 Promise 的核心,它返回一个新的 Promise

 1MyPromise.prototype.then = function (onResolved, onRejected) {
 2  var self = this;
 3  var promise2;
 4  
 5  
 6  onResolved = typeof onResolved === 'function' ? onResolved : v => v;
 7  onRejected = typeof onRejected === 'function' ? onRejected : r => { throw r };
 8
 9  if (self.currentState === RESOLVED) {
10    return (promise2 = new MyPromise(function (resolve, reject) {
11      setTimeout(function () {
12        try {
13          var x = onResolved(self.value);
14          resolutionProcedure(promise2, x, resolve, reject);
15        } catch (reason) {
16          reject(reason);
17        }
18      });
19    }));
20  }
21  
22  
23}

四、Promise 高级静态方法实现

1. Promise.all 实现

Promise.all 接收一个 Promise 数组,当所有 Promise 都成功时返回结果数组,有一个失败则立即失败

 1Promise.all = function(promises) {
 2  return new Promise((resolve, reject) => {
 3    let result = [];
 4    let index = 0;
 5    let len = promises.length;
 6    if(len === 0) {
 7      resolve(result);
 8      return;
 9    }
10
11    for(let i = 0; i < len; i++) {
12      Promise.resolve(promises[i]).then(data => {
13        result[i] = data;
14        index++;
15        if(index === len) resolve(result);
16      }).catch(err => {
17        reject(err);
18      })
19    }
20  })
21}

2. Promise.race 实现

Promise.race 返回第一个完成的 Promise 的结果。

 1Promise.race = function(promises) {
 2  return new Promise((resolve, reject) => {
 3    let len = promises.length;
 4    if(len === 0) return;
 5    for(let i = 0; i < len; i++) {
 6      Promise.resolve(promises[i]).then(data => {
 7        resolve(data);
 8        return;
 9      }).catch(err => {
10        reject(err);
11        return;
12      })
13    }
14  })
15}

3. Promise.allSettled 实现

Promise.allSettled 等待所有 Promise 完成无论成功或失败

 1function allSettled(iterable) {
 2  return new Promise((resolve, reject) => {
 3    function addElementToResult(i, elem) {
 4      result[i] = elem;
 5      elementCount++;
 6      if (elementCount === result.length) {
 7        resolve(result);
 8      }
 9    }
10
11    let index = 0;
12    for (const promise of iterable) {
13      const currentIndex = index;
14      promise.then(
15        (value) => addElementToResult(
16          currentIndex, {
17            status: 'fulfilled',
18            value
19          }),
20        (reason) => addElementToResult(
21          currentIndex, {
22            status: 'rejected',
23            reason
24          }));
25      index++;
26    }
27    if (index === 0) {
28      resolve([]);
29      return;
30    }
31    let elementCount = 0;
32    const result = new Array(index);
33  });
34}

代码:完整 Promise 实现

下面是一个符合 Promise/A+ 规范的完整实现:

 1const PENDING = "pending";
 2const RESOLVED = "resolved";
 3const REJECTED = "rejected";
 4
 5function MyPromise(fn) {
 6  let _this = this;
 7  _this.currentState = PENDING;
 8  _this.value = undefined;
 9  _this.resolvedCallbacks = [];
10  _this.rejectedCallbacks = [];
11
12  _this.resolve = function (value) {
13    if (value instanceof MyPromise) {
14      return value.then(_this.resolve, _this.reject)
15    }
16    setTimeout(() => {
17      if (_this.currentState === PENDING) {
18        _this.currentState = RESOLVED;
19        _this.value = value;
20        _this.resolvedCallbacks.forEach(cb => cb());
21      }
22    })
23  };
24
25  _this.reject = function (reason) {
26    setTimeout(() => {
27      if (_this.currentState === PENDING) {
28        _this.currentState = REJECTED;
29        _this.value = reason;
30        _this.rejectedCallbacks.forEach(cb => cb());
31      }
32    })
33  }
34  
35  try {
36    fn(_this.resolve, _this.reject);
37  } catch (e) {
38    _this.reject(e);
39  }
40}
41
42
43MyPromise.prototype.then = function (onResolved, onRejected) {
44  var self = this;
45  var promise2;
46  
47  onResolved = typeof onResolved === 'function' ? onResolved : v => v;
48  onRejected = typeof onRejected === 'function' ? onRejected : r => { throw r };
49
50  if (self.currentState === RESOLVED) {
51    return (promise2 = new MyPromise(function (resolve, reject) {
52      setTimeout(function () {
53        try {
54          var x = onResolved(self.value);
55          resolutionProcedure(promise2, x, resolve, reject);
56        } catch (reason) {
57          reject(reason);
58        }
59      });
60    }));
61  }
62  
63  
64};
65
66
67function resolutionProcedure(promise2, x, resolve, reject) {
68  if (promise2 === x) {
69    return reject(new TypeError("Error"));
70  }
71  
72  if (x instanceof MyPromise) {
73    if (x.currentState === PENDING) {
74      x.then(function (value) {
75        resolutionProcedure(promise2, value, resolve, reject);
76      }, reject);
77    } else {
78      x.then(resolve, reject);
79    }
80    return;
81  }
82  
83  let called = false;
84  if (x !== null && (typeof x === "object" || typeof x === "function")) {
85    try {
86      let then = x.then;
87      if (typeof then === "function") {
88        then.call(
89          x,
90          y => {
91            if (called) return;
92            called = true;
93            resolutionProcedure(promise2, y, resolve, reject);
94          },
95          e => {
96            if (called) return;
97            called = true;
98            reject(e);
99          }
100        );
101      } else {
102        resolve(x);
103      }
104    } catch (e) {
105      if (called) return;
106      called = true;
107      reject(e);
108    }
109  } else {
110    resolve(x);
111  }
112}
  1. 状态管理:Promise 的状态一旦改变就不能再变
  2. 异步执行:then 方法的回调需要异步执行
  3. 链式调用:then 方法必须返回一个新的 Promise
  4. 值穿透:then 的参数如果不是函数需要忽略
  5. Promise 解析过程:处理 thenable 对象和循环引用

总结

Promise 的核心在于状态管理链式调用异步处理

个人笔记记录 2021 ~ 2025