手动Promise / A+ (ES6)

本文最后更新于:2023年3月19日 晚上

本文转自:https://juejin.im/post/6860037916622913550#heading-10

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
const PENDING = "PENDING"; // 进行中
const FULFILLED = "FULFILLED"; // 已成功
const REJECTED = "REJECTED"; // 已失败

class myPromise {
constructor(executor) {
// 请求状态
this.status = PENDING;
// 成功结果
this.value = null;
// 失败原因
this.reason = null;
// 成功态回调队列
this.onFulfilledCallbacks = [];
// 失败态回调队列
this.onRejectedCallbacks = [];

const resolve = (value) => {
console.log(value);
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
this.onFulfilledCallbacks.forEach((fn) => fn(this.value));
}
};
const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach((fn) => fn(this.reason));
}
};
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}

then(onFulfilled, onRejected) {
if (typeof onFulfilled !== "function") onFulfilled = (value) => value;
if (typeof onRejected !== "function")
onRejected = (reason) => {
throw reason;
};
const self = this;
return new myPromise((resolve, reject) => {
if (self.status === PENDING) {
self.onFulfilledCallbacks.push(() => {
try {
setTimeout(() => {
const res = onFulfilled(self.value);
if (res instanceof myPromise) {
res.then(resolve, reject);
} else {
resolve(res);
}
});
} catch (error) {
reject(error);
}
});
self.onRejectedCallbacks.push(() => {
try {
setTimeout(() => {
const res = onRejected(self.value);
if (res instanceof myPromise) {
res.then(resolve, reject);
} else {
reject(res);
}
});
} catch (error) {
reject(error);
}
});
} else if (self.status === FULFILLED) {
try {
setTimeout(() => {
const res = onFulfilled(self.value);
if (res instanceof myPromise) {
res.then(resolve, reject);
} else {
resolve(res);
}
});
} catch (error) {
reject(error);
}
} else if (self.status === REJECTED) {
try {
setTimeout(() => {
const res = onRejected(self.reason);
if (res instanceof myPromise) {
res.then(resolve, reject);
} else {
reject(res);
}
});
} catch (error) {
reject(error);
}
}
});
}

catch(onRejected) {
return this.then(null, onRejected);
}

static reject(reason) {
return new myPromise((resolve, reject) => reject(reason));
}
static resolve(value) {
if (value instanceof myPromise) return value;
else return new myPromise((resolve, reject) => resolve(value));
}

static all(promises) {
let promisesLength = promises.length;
let count = 0;
const result = new Array(promisesLength);
return new myPromise((resolve, reject) => {
promises.forEach((promise, i) => {
myPromise
.resolve(promise)
.then((res) => {
result[i] = res;
count++;
if (count === promisesLength) {
resolve(result);
}
})
.catch((err) => {
reject(err);
});
});
});
}
static race(promises) {
return new myPromise((resolve, reject) => {
promises.forEach((promise) => {
myPromise
.resolve(promise)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
});
}
}

let promise1 = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
});
let promise2 = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve(2);
}, 2000);
});
let promise3 = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve(3);
}, 3000);
});

myPromise.all([1, 2, 3]).then(([res1, res2, res3]) => {
console.log(res1, res2, res3);
});

myPromise.race([1, 2, 3]).then((res) => {
console.log(res);
});

前言

写这篇文章的目的是解剖 Promise 源码,起因也是最近秋招被问到了让手写 Promise,另外在网上看到的 Promise 源码或多或少有些小问题,也就是没有完全遵循 Promise/A+规范。
代码会完全使用ES6语法,主要分以下几个模块:

  • 整体分析(为代码书写铺路)
  • 实现初版(构造函数大致功能亿完善)
  • 支持异步和链式调用(完善 then 方法)
  • 实现 catch 方法
  • 实现 Promise.resolve()
  • 实现 Promise.reject()
  • 实现 Promise.all()
  • 实现 Promise.race()

一、整体分析

所谓 Promise 就是一个容器,有三个状态:PENDING(进行中)、FULFILLED(成功)、REJECTED(失败),里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,有两大特点:

  • 容器状态不受外界影响
  • 一旦状态改变就不会再变,任何时候都可以得到这个结果

来看下 Promise 的用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
new Promise((resolve, reject) => {
// ...
// 成功则执行resolve,否则指定reject
}).then(
res => {
// resolve对应触发函数的执行
},
err => {
// reject对应触发函数的执行
}
).then(
// 支持链式调用
res => {

}
).catch(
err => console.log(err)
)
Promise.resolve();
Promise.reject();
Promise.all([promise1, promise2, ...]).then();
Promise.race([promise1, promise2, ...]).then();
复制代码

通过用法不难分析出:

  • Promise 构造函数接受一个函数参数exector,exector 接受resolvereject两个函数并立即执行,通过resolve/reject改变状态
  • 状态改变后,触发原型链上的then、catch方法
  • Promise 类拥有静态方法resolve、reject、all、race

那么可以写出大致结构代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Promise {
constructor(exector) {
const resolve = () => {
}
const reject = () => {
}
exector(resolve, reject);
}
then() {
}
catch() {
}
static resolve() {
}
static reject() {
}
static all() {
}
static race() {

}
}
复制代码

之后在此基础上补充代码。

二、实现初版

首先引入三种状态,完善resolvereject函数,最后在构造函数内执行exector(resolve, reject)

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
// 定义三种状态
const PENDING = 'PENDING'; // 进行中
const FULFILLED = 'FULFILLED'; // 已成功
const REJECTED = 'REJECTED'; // 已失败
class Promise {
constructor(exector) {
// 初始化状态
this.status = PENDING;
// 将成功、失败结果放在this上,便于then、catch访问
this.value = undefined;
this.reason = undefined;
const resolve = value => {
// 只有进行中状态才能更改状态
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
}
}
const reject = reason => {
// 只有进行中状态才能更改状态
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
}
}
// 立即执行exector
// 把内部的resolve和reject传入executor,用户可调用resolve和reject
exector(resolve, reject);
}
}
复制代码

注意:exector(resolve, reject);执行可能会报错,所以需要使用try包括一下,有报错reject抛出去。

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
constructor(exector) {
// 初始化状态
this.status = PENDING;
// 将成功、失败结果放在this上,便于then、catch访问
this.value = undefined;
this.reason = undefined;
const resolve = value => {
if (this.status === PENDING) {
// 只有进行中状态才能更改状态
this.status = FULFILLED;
this.value = value;
}
}
const reject = reason => {
if (this.status === PENDING) {
// 只有进行中状态才能更改状态
this.status = REJECTED;
this.reason = reason;
}
}
// 修改代码
try {
// 立即执行executor
// 把内部的resolve和reject传入executor,用户可调用resolve和reject
exector(resolve, reject);
} catch(e) {
// executor执行出错,将错误内容reject抛出去
reject(e);
}
}
复制代码

此时可以使用then进行捕获了,then接收两个函数,分别对应FULFILLEDREJECTED状态:

1
2
3
4
5
new Promise().then(
res => {},
err => {},
)
复制代码

注意:thencatch是微任务,这里使用setTimeout模拟:

1
2
3
4
5
6
7
8
9
10
11
12
13
then(onFulfilled, onRejected) {
// then是微任务,这里用setTimeout模拟
setTimeout(() => {
if (this.status === FULFILLED) {
// FULFILLED状态下才执行
onFulfilled(this.value);
} else if (this.status === REJECTED) {
// REJECTED状态下才执行
onRejected(this.reason);
}
})
}
复制代码

OK,初版已经完成:

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
// 定义三种状态
const PENDING = 'PENDING'; // 进行中
const FULFILLED = 'FULFILLED'; // 已成功
const REJECTED = 'REJECTED'; // 已失败
class Promise {
constructor(exector) {
// 初始化状态
this.status = PENDING;
// 将成功、失败结果放在this上,便于then、catch访问
this.value = undefined;
this.reason = undefined;
const resolve = value => {
if (this.status === PENDING) {
// 只有进行中状态才能更改状态
this.status = FULFILLED;
this.value = value;
}
}
const reject = reason => {
if (this.status === PENDING) {
// 只有进行中状态才能更改状态
this.status = REJECTED;
this.reason = reason;
}
}
try {
// 立即执行executor
// 把内部的resolve和reject传入executor,用户可调用resolve和reject
exector(resolve, reject);
} catch(e) {
// executor执行出错,将错误内容reject抛出去
reject(e);
}
}
then(onFulfilled, onRejected) {
// then是微任务,这里用setTimeout模拟
setTimeout(() => {
if (this.status === FULFILLED) {
// FULFILLED状态下才执行
onFulfilled(this.value);
} else if (this.status === REJECTED) {
// REJECTED状态下才执行
onRejected(this.reason);
}
})
}
}
复制代码

可以拿数据测试一下:

1
2
3
4
5
6
7
const promise = new Promise((resolve, reject) => {
Math.random() < 0.5 ? resolve(1) : reject(-1);
}).then(
res => console.log(res),
err => console.log(err),
)
复制代码

三、支持异步和链式调用

此时初版还有三个方向需要完善:

  1. Promise 内部异步代码执行的问题。
  2. Promise 的链式调用
  3. 值传透

支持异步代码

开发中经常会将接口放于promise内部,等接口请求响应成功把数据resolve出去,或失败时把数据reject出去,此时thencatch才会进行捕获。
而现在的代码,promise内部如果有异步代码执行后才resolvethen不会等待异步代码执行完毕会直接执行,所以此时状态是PENDING,不会触发then的回调函数。
新增onFulfilledCallbacksonRejectedCallbacks维护成功态、失败态任务队列:

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
// 定义三种状态
const PENDING = 'PENDING'; // 进行中
const FULFILLED = 'FULFILLED'; // 已成功
const REJECTED = 'REJECTED'; // 已失败
class Promise {
constructor(exector) {
// 初始化状态
this.status = PENDING;
// 将成功、失败结果放在this上,便于then、catch访问
this.value = undefined;
this.reason = undefined;

// 新增代码:
// 成功态回调函数队列
this.onFulfilledCallbacks = [];
// 失败态回调函数队列
this.onRejectedCallbacks = [];
const resolve = value => {
// 只有进行中状态才能更改状态
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
// 新增代码:
// 成功态函数依次执行
this.onFulfilledCallbacks.forEach(fn => fn(this.value));
}
}
const reject = reason => {
// 只有进行中状态才能更改状态
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
// 新增代码:
// 失败态函数依次执行
this.onRejectedCallbacks.forEach(fn => fn(this.reason))
}
}
try {
// 立即执行executor
// 把内部的resolve和reject传入executor,用户可调用resolve和reject
exector(resolve, reject);
} catch(e) {
// executor执行出错,将错误内容reject抛出去
reject(e);
}
}
then(onFulfilled, onRejected) {
// then是微任务,这里用setTimeout模拟
setTimeout(() => {
// 新增代码:
if (this.status === PENDING) {
// 状态是PENDING下执行
// 说明promise内部有异步代码执行,还未改变状态,添加到成功/失败回调任务队列即可
this.onFulfilledCallbacks.push(onFulfilled);
this.onRejectedCallbacks.push(onRejected);
}else if (this.status === FULFILLED) {
// FULFILLED状态下才执行
onFulfilled(this.value);
} else if (this.status === REJECTED) {
// REJECTED状态下才执行
onRejected(this.reason);
}
})
}
}
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 1000);
}).then(
res => console.log(res)
)
// 1
复制代码

实现链式调用

Promise的一大优势就是支持链式调用,具体来说就是then方法的具体实现,实际上是返回了一个Promise,需要注意的几个点:

  1. 保存之前 promise 实例的引用,即保存this
  2. 根据then回调函数执行的返回值
  • 如果是 promise 实例,那么返回的下一个 promise 实例会等待这个 promise 状态发生变化
  • 如果不是 promise 实例,根据目前情况直接执行resolvereject

完善then函数:

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
then(onFulfilled, onRejected) {
// 保存this
const self = this;
return new Promise((resolve, reject) => {
if (self.status === PENDING) {
self.onFulfilledCallbacks.push(() => {
// try捕获错误
try {
// 模拟微任务
setTimeout(() => {
const result = onFulfilled(self.value);
// 分两种情况:
// 1. 回调函数返回值是Promise,执行then操作
// 2. 如果不是Promise,调用新Promise的resolve函数
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
})
} catch(e) {
reject(e);
}
});
self.onRejectedCallbacks.push(() => {
// 以下同理
try {
setTimeout(() => {
const result = onRejected(self.reason);
// 不同点:此时是reject
result instanceof Promise ? result.then(resolve, reject) : reject(result);
})
} catch(e) {
reject(e);
}
})
} else if (self.status === FULFILLED) {
setTimeout(() => {
try {
const result = onFulfilled(self.value);
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
} catch(e) {
reject(e);
}
});
} else if (self.status === REJECT){
setTimeout(() => {
try {
const result = onRejected(self.error);
result instanceof Promise ? result.then(resolve, reject) : reject(result);
} catch(e) {
reject(e);
}
})
}
})
}
复制代码

值传透

Promise支持值穿透:

1
2
3
4
5
6
7
8
9
10
let promsie = new Promise((resolve,reject)=>{
resolve(1)
})
.then(2)
.then(3)
.then(value => {
console.log(value)
})
// 1
复制代码

then参数期望是函数,传入非函数则会发生值穿透。值传透可以理解为,当传入 then 的不是函数的时候,这个 then 是无效的。
原理上是当 then 中传入的不算函数,则这个promise返回上一个promise的值,这就是发生值穿透的原因,所以只需要对then的两个参数进行设置就行了:

1
2
3
4
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function'? onRejected:
reason => { throw new Error(reason instanceof Error ? reason.message:reason) }
复制代码

完整的 then 函数代码:

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
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function'? onRejected:
reason => { throw new Error(reason instanceof Error ? reason.message:reason) }
// 保存this
const self = this;
return new Promise((resolve, reject) => {
if (self.status === PENDING) {
self.onFulfilledCallbacks.push(() => {
// try捕获错误
try {
// 模拟微任务
setTimeout(() => {
const result = onFulfilled(self.value);
// 分两种情况:
// 1. 回调函数返回值是Promise,执行then操作
// 2. 如果不是Promise,调用新Promise的resolve函数
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
})
} catch(e) {
reject(e);
}
});
self.onRejectedCallbacks.push(() => {
// 以下同理
try {
setTimeout(() => {
const result = onRejected(self.reason);
// 不同点:此时是reject
result instanceof Promise ? result.then(resolve, reject) : reject(result);
})
} catch(e) {
reject(e);
}
})
} else if (self.status === FULFILLED) {
try {
setTimeout(() => {
const result = onFulfilled(self.value);
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
});
} catch(e) {
reject(e);
}
} else if (self.status === REJECTED){
try {
setTimeout(() => {
const result = onRejected(self.reason);
result instanceof Promise ? result.then(resolve, reject) : reject(result);
})
} catch(e) {
reject(e);
}
}
});
}
复制代码

四、实现 catch()方法

Promise.prototype.catch就是Promise.prototype.then(null, onRejected)的别名,所以实现就很简单了:

1
2
3
4
catch(onRejected) {
return this.then(null, onRejected);
}
复制代码

五、Promise.resolve()

这里就不考虑参数是thenable对象了,那么参数有两种情况:

  1. Promise实例
  2. 不是Promise实例
1
2
3
4
5
6
7
8
9
10
static resolve(value) {
if (value instanceof Promise) {
// 如果是Promise实例,直接返回
return value;
} else {
// 如果不是Promise实例,返回一个新的Promise对象,状态为FULFILLED
return new Promise((resolve, reject) => resolve(value));
}
}
复制代码

六、Promise.reject()

Promise.reject也会返回一个 Promise 实例,状态为REJECTED
Promise.resolve不同的是,Promise.reject方法的参数会原封不动地作为reject的参数

1
2
3
4
5
6
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason);
})
}
复制代码

七、Promise.all()

返回一个 promise 对象,只有当所有 promise 都成功时返回的 promise 状态才成功,需要注意的点是:

  1. 所有的 promise 状态变为FULFILLED,返回的 promise 状态才变为FULFILLED
  2. 一个 promise 状态变为REJECTED,返回的 promise 状态就变为REJECTED
  3. 数组成员不一定都是 promise,需要使用Promise.resolve()处理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static all(promiseArr) {
const len = promiseArr.length;
const values = new Array(len);
// 记录已经成功执行的promise个数
let count = 0;
return new Promise((resolve, reject) => {
for (let i = 0; i < len; i++) {
// Promise.resolve()处理,确保每一个都是promise实例
Promise.resolve(promiseArr[i]).then(
val => {
values[i] = val;
count++;
// 如果全部执行完,返回promise的状态就可以改变了
if (count === len) resolve(values);
},
err => reject(err),
);
}
})
}
复制代码

八、Promise.race()

Promise.race()实现就比较简单了:

1
2
3
4
5
6
7
8
9
10
11
static race(promiseArr) {
return new Promise((resolve, reject) => {
promiseArr.forEach(p => {
Promise.resolve(p).then(
val => resolve(val),
err => reject(err),
)
})
})
}
复制代码

九、完整代码

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
// 定义三种状态
const PENDING = 'PENDING'; // 进行中
const FULFILLED = 'FULFILLED'; // 已成功
const REJECTED = 'REJECTED'; // 已失败
class Promise {
constructor(exector) {
// 初始化状态
this.status = PENDING;
// 将成功、失败结果放在this上,便于then、catch访问
this.value = undefined;
this.reason = undefined;
// 成功态回调函数队列
this.onFulfilledCallbacks = [];
// 失败态回调函数队列
this.onRejectedCallbacks = [];
const resolve = value => {
// 只有进行中状态才能更改状态
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
// 成功态函数依次执行
this.onFulfilledCallbacks.forEach(fn => fn(this.value));
}
}
const reject = reason => {
// 只有进行中状态才能更改状态
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
// 失败态函数依次执行
this.onRejectedCallbacks.forEach(fn => fn(this.reason))
}
}
try {
// 立即执行executor
// 把内部的resolve和reject传入executor,用户可调用resolve和reject
exector(resolve, reject);
} catch(e) {
// executor执行出错,将错误内容reject抛出去
reject(e);
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function'? onRejected:
reason => { throw new Error(reason instanceof Error ? reason.message:reason) }
// 保存this
const self = this;
return new Promise((resolve, reject) => {
if (self.status === PENDING) {
self.onFulfilledCallbacks.push(() => {
// try捕获错误
try {
// 模拟微任务
setTimeout(() => {
const result = onFulfilled(self.value);
// 分两种情况:
// 1. 回调函数返回值是Promise,执行then操作
// 2. 如果不是Promise,调用新Promise的resolve函数
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
})
} catch(e) {
reject(e);
}
});
self.onRejectedCallbacks.push(() => {
// 以下同理
try {
setTimeout(() => {
const result = onRejected(self.reason);
// 不同点:此时是reject
result instanceof Promise ? result.then(resolve, reject) : reject(result);
})
} catch(e) {
reject(e);
}
})
} else if (self.status === FULFILLED) {
try {
setTimeout(() => {
const result = onFulfilled(self.value);
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
});
} catch(e) {
reject(e);
}
} else if (self.status === REJECTED){
try {
setTimeout(() => {
const result = onRejected(self.reason);
result instanceof Promise ? result.then(resolve, reject) : reject(result);
})
} catch(e) {
reject(e);
}
}
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
static resolve(value) {
if (value instanceof Promise) {
// 如果是Promise实例,直接返回
return value;
} else {
// 如果不是Promise实例,返回一个新的Promise对象,状态为FULFILLED
return new Promise((resolve, reject) => resolve(value));
}
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason);
})
}
static all(promiseArr) {
const len = promiseArr.length;
const values = new Array(len);
// 记录已经成功执行的promise个数
let count = 0;
return new Promise((resolve, reject) => {
for (let i = 0; i < len; i++) {
// Promise.resolve()处理,确保每一个都是promise实例
Promise.resolve(promiseArr[i]).then(
val => {
values[i] = val;
count++;
// 如果全部执行完,返回promise的状态就可以改变了
if (count === len) resolve(values);
},
err => reject(err),
);
}
})
}
static race(promiseArr) {
return new Promise((resolve, reject) => {
promiseArr.forEach(p => {
Promise.resolve(p).then(
val => resolve(val),
err => reject(err),
)
})
})
}
}

作者:洛霞
链接:https://juejin.im/post/6860037916622913550
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!