promise实现

# promise实现

// 定义三个状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

class MyPromise {
 constructor(executor) {
  try {
   executor(this.resolve, this.reject)
  } catch (error) {
   this.reject(error)
  }
 }

 // 存储初始化状态
 status = PENDING;
 // 成功值
 value = null;
 // 失败原因
 reason = null;

 // 成功存储状态
 onFulfilledCallbacks = [];
 // 失败存储状态
 onRejectedCallbacks = [];

 // 成功
 resolve = (value) => {
  // 只有状态为pending时才能改变
  if (this.status === PENDING) {
   this.status = FULFILLED
   this.value = value
   // 存在值拿出来执行
   while (this.onFulfilledCallbacks.length > 0) {
    this.onFulfilledCallbacks.shift()(value)
   }
  }
 };

 reject = (reason) => {
  if (this.status === PENDING) {
   this.status = REJECTED
   this.reason = reason
   while (this.onRejectedCallbacks.length > 0) {
    this.onRejectedCallbacks.shift()(reason)
   }
  }
 };

 // then 接受两个参数
 then(onFulfilled, onRejected) {
  // 如果时函数就处理
  const realOnFulfilled = 
   typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
  const realOnRejected =
   typeof onRejected === 'function' ? onRejected : (reason) => throw reason;

  // 链式调用
  const promise2 = new MyPromise((resolve, reject) => {
   // 创建一个微任务
   const fulfilledMicrotask = () => {
    queueMicrotask(() => {
     try {
      // 获取成功回调的函数执行结果
      const x = realOnFulfilled(this.value)

      // 传入 resolvePromise 集中处理
      resolvePromise(promise2, x, resolve, reject)
     } catch (error) {
      reject(error)
     }
    })
   }
   

   const rejectedMicrotask = () => {
    queueMicrotask(() => {
     try {
      // 调用失败回调,并且把原因返回
      const x = realOnRejected(this.reason)

      // 传入 resolvePromise 集中处理
      resolvePromise(promise2, x, resolve, reject)
     } catch (error) {
      reject(error)
     }
    })
   }

   // 判断状态
   if (this.status === FULFILLED) {
    fulfilledMicrotask();
   } else if (this.status === REJECTED) {
    rejectedMicrotask()
   } else if (this.status === PENDING) {
    // 等待
    this.onFulfilledCallbacks.push(fulfilledMicrotask)
    this.onRejectedCallbacks.push(rejectedMicrotask)
   }
  });
  return promise2
 };

 catch (onRejected) {
  // 只需要对错误处理
  this.then(undefined, onRejected);
 }

 finally(fn) {
  return this.then(
   (value) => {
    return MyPromise.resolve(fn()).then(() => {
     return value;
    });
   },
   (error) => {
    return MyPromise.resolve(fn()).then(() => {
     throw error;
    });
   }
  );
 };


 // resolve静态方法
 static resolve(value) {
  // 如果传入 MyPromise 就直接返回
  if (value instanceof MyPromise) {
   return value
  }

  // 转成常规方式
  return new MyPromise((resolve) => {
   resolve(value);
  });
 };

 static reject(reason) {
  return new MyPromise((reject) => {
   reject(reason);
  });
 };

 static all(promiseList) {
  return new MyPromise((resolve, reject) => {
   const result = [];
   const length = promiseList.length;
   let count = 0;

   if (length === 0) {
    return resolve(result);
   }

   promiseList.forEach((promise, index) => {
    MyPromise.resolve(promise).then(
     (value) => {
      count++;
      result[index] = value;
      if (count === length) {
       resolve(result);
      }
     },
     (reason) => {
      reject(reason);
     }
    );
   });
  });
 }

 static allSettled(promiseList) {
  return new MyPromise((resolve) => {
   const length = promiseList.length;
   const result = [];
   let count = 0;

   if (length === 0) {
    return resolve(result);
   } else {
    for (let i = 0; i < length; i++) {
     const currentPromise = MyPromise.resolve(promiseList[i]);
     currentPromise.then(
      (value) => {
       count++;
       result[i] = {
        status: 'fulfilled',
        value: value,
       };
       if (count === length) {
        return resolve(result);
       }
      },
      (reason) => {
       count++;
       result[i] = {
        status: 'rejected',
        reason: reason,
       };
       if (count === length) {
        return resolve(result);
       }
      }
     )
    }
   }
  });
 }

 static any(promiseList) {
  return new MyPromise((resolve, reject) => {
      if (promiseList.length === 0) return reject('All promises were rejected')

      const errors = []
      let count = 0

      for (let [i, p] of promiseList.entries()) {
          this.resolve(p).then(
              res => {
                  resolve(res)
              },
              err => {
                  errors[i] = err;
                  count++;
                  if (count === promiseList.length) reject(errors);;
              }
          );
      }
  })
 }

 static race(promiseList) {
  return new MyPromise((resolve, reject) => {
      const length = promiseList.length;

      if (length === 0) {
          return resolve();
      } else {
          for (let i = 0; i < length; i++) {
              MyPromise.resolve(promiseList[i]).then(
                  (value) => {
                      return resolve(value);
                  },
                  (reason) => {
                      return reject(reason);
                  }
              );
          }
      }
  });
 }

}

function resolvePromise(promise, x, resolve, reject) {
    // 如果 promise 和 x 指向同一对象,以 TypeError 为据因拒绝执行 promise
    // 这是为了防止死循环
    if (promise === x) {
        return reject(
            new TypeError("The promise and the return value are the same")
        );
    }

    if (typeof x === "object" || typeof x === "function") {
        // 这个坑是跑测试的时候发现的,如果x是null,应该直接resolve
        if (x === null) {
            return resolve(x);
        }

        let then;
        try {
            // 把 x.then 赋值给 then
            then = x.then;
        } catch (error) {
            // 如果取 x.then 的值时抛出错误 e ,则以 e 为据因拒绝 promise
            return reject(error);
        }

        // 如果 then 是函数
        if (typeof then === "function") {
            let called = false;
            // 将 x 作为函数的作用域 this 调用之
            // 传递两个回调函数作为参数,第一个参数叫做 resolvePromise ,第二个参数叫做 rejectPromise
            // 名字重名了,我直接用匿名函数了
            try {
                then.call(
                    x,
                    // 如果 resolvePromise 以值 y 为参数被调用,则运行 [[Resolve]](promise, y)
                    (y) => {
                        // 如果 resolvePromise 和 rejectPromise 均被调用,
                        // 或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用
                        // 实现这条需要前面加一个变量called
                        if (called) return;
                        called = true;
                        resolvePromise(promise, y, resolve, reject);
                    },
                    // 如果 rejectPromise 以据因 r 为参数被调用,则以据因 r 拒绝 promise
                    (r) => {
                        if (called) return;
                        called = true;
                        reject(r);
                    }
                );
            } catch (error) {
                // 如果调用 then 方法抛出了异常 e:
                // 如果 resolvePromise 或 rejectPromise 已经被调用,则忽略之
                if (called) return;

                // 否则以 e 为据因拒绝 promise
                reject(error);
            }
        } else {
            // 如果 then 不是函数,以 x 为参数执行 promise
            resolve(x);
        }
    } else {
        // 如果 x 不为对象或者函数,以 x 为参数执行 promise
        resolve(x);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
上次更新: 2022/7/28 下午9:01:35