手写 promise
1.Promise 构造函数
- 参数 构造函数接受一个函数作为参数,该函数有两个参数也是函数
- resolve 函数用于将 Promise 对象的状态从 pending 变为 fulfilled
- reject 函数用于将 Promise 对象的状态从 pending 变为 rejected
- 状态三个:pending、fulfilled 和 rejected,状态不可逆
- 构造函数: executor 函数中,所以 promise 本身是同步的,then\catch 才是异步
下面是一个Promise构造器的简单实现
1const PENDING = 'pending'
2const FULFILLED = 'fulfilled'
3const REJECTED = 'rejected'
4
5class MyPromise {
6 constructor(executor) {
7 this.status = PENDING
8 this.reason = undefined
9
10 const resolve = (value) => {
11 if (this.status !== PENDING) return
12 this.status = FULFILLED
13 this.reason = value
14 }
15
16 const reject = (reason) => {
17 if (this.status !== PENDING) return
18 this.status = REJECTED
19 this.reason = reason
20 }
21
22 try {
23 executor(resolve, reject)
24 } catch (error) {
25 reject(error)
26 }
27 }
28}
2.then 方法
- 参数,分别是 onFulfilled 和 onRejected,这两个参数都是函数
- 链式调用,因为返回一个新的 Promise 对象,该对象的状态由 onFulfilled 和 onRejected 的返回值决定
- 微任务,把 onFulfilled、onRejected、resolve、reject 存起来,等到 Promise 的状态改变时,再执行。可以使用数组来存储这些函数,当状态改变时,依次执行这些函数
1const PENDING = 'pending'
2const FULFILLED = 'fulfilled'
3const REJECTED = 'rejected'
4
5class MyPromise {
6 #status = PENDING
7 #reason = null
8 #handlers = []
9
10 constructor(executor) {
11 const resolve = (reason) => {
12 this.#changeState(FULFILLED, reason)
13 }
14 const reject = (reason) => {
15 this.#changeState(REJECTED, reason)
16 }
17 try {
18 executor(resolve, reject)
19 } catch (error) {
20 reject(error)
21 }
22 }
23 then(onFulfilled, onRejected) {
24 return new MyPromise((resolve, reject) => {
25 this.#handlers.push({
26 onFulfilled,
27 onRejected,
28 resolve,
29 reject,
30 })
31 this.#run()
32 })
33 }
34
35
36 * promise 状态发生改变时:记录状态及结果,并执行run函数
37 * @param {*} state 状态
38 * @param {*} reason 结果
39 * @returns
40 */
41 #changeState(state, reason) {
42 if (this.#status !== PENDING) return
43 this.#status = state
44 this.#reason = reason
45 this.#run()
46 }
47
48 * run函数:辅助then函数返回的promise对象有结果时,
49 * 遍历执行所有onFulfilled、onRejected 并把结果传递给下一个promise对象
50 * @returns
51 */
52 #run() {
53 if (this.#status === PENDING) return
54 while (this.#handlers.length) {
55 const { onFulfilled, onRejected, resolve, reject } =
56 this.#handlers.shift()
57 let fn = this.#status === FULFILLED ? onFulfilled : onRejected
58 this.#runFn(fn, resolve, reject)
59 }
60 }
61
62 * setTimeout执行模拟微任务的执行环境
63 * @param {*} fn onFulfilled | onRejected
64 * @param {*} resolve 通过resolve传递给下一个promise对象
65 * @param {*} reject
66 *
67 */
68 #runFn(fn, resolve, reject) {
69 setTimeout(() => {
70 if (typeof fn !== 'function') {
71 let settled = this.#status === FULFILLED ? resolve : reject
72 settled(this.#reason)
73 return
74 }
75 try {
76 const res = fn(this.#reason)
77
78 resolve(res)
79 } catch (error) {
80 reject(error)
81 }
82 }, 0)
83 }
84}
85
86const p = new MyPromise((resolve, reject) => {
87 console.log('promise')
88 setTimeout(() => {
89 reject('123')
90 }, 1000)
91})
92p.then(
93 (res) => {
94 console.log(res)
95 },
96 (err) => {
97 console.log(err, 'err')
98 }
99)
100p.then(
101 (res) => {
102 console.log(res)
103 },
104 (err) => {
105 console.log(err, 'err2')
106 }
107)
3.catch 方法
- catch 方法是状态为 REJECTED 时的处理函数
- 和 then 不同的是 只接受一个 onRejected 参数 下面是利用 then 实现
1catch(onRejected) {
2 return this.then(null, onRejected);
3}
4.resolve 方法
- resolve 方法返回一个状态为 FULFILLED 的 promise 对象
- 接受一个参数 value
- 如果 value 是一个 promise 对象,则返回该 promise 对象
- 否则,返回一个状态为 FULFILLED 的 promise 对象,其值为 value
1static resolve(value) {
2 if (value instanceof MyPromise) return value
3 return new MyPromise((resolve, reject) => {
4 resolve(value)
5 })
6}
5.reject 方法
- reject 方法返回一个状态为 REJECTED 的 promise 对象
- 接受一个参数 reason
1static reject(reason) {
2 return new MyPromise((resolve, reject) => {
3 reject(reason)
4 })
5}
6.finally 方法
- finally 方法接受一个回调函数作为参数
- 无论 promise 对象的状态是 FULFILLED 还是 REJECTED,都会执行该回调函数
- finally 方法返回一个 promise 对象,其状态和值与原 promise 对象相同
- 利用 then, 失败和成功都执行一下回调
1finally(onFinally) {
2 return this.then(
3 value => MyPromise.resolve(onFinally()).then(() => value),
4 reason => MyPromise.resolve(onFinally()).then(() => {
5 throw reason
6 })
7 )
8}
7.all 方法
- all 方法接受一个 promise 对象的数组作为参数
- 返回值:有一个失败,则返回失败,否则返回成功
- 往往项目中是所有成功或者失败的结果都要,就使用 allSettled
1static all(promiseArr) {
2 if (typeof promiseArr[Symbol.iterator] !== 'function') {
3 throw new Error('参数必须是可迭代对象')
4 }
5 return new MyPromise((resolve, reject) => {
6 let result = []
7 let count = 0
8 for (let i = 0; i < promiseArr.length; i++) {
9 promiseArr[i].then(res => {
10 result[i] = res
11 count++
12 if (count === promiseArr.length) {
13 resolve(result)
14 }
15 }, err => {
16 reject(err)
17 })
18 }
19 })
20}
8. allSettled 方法
- allSettled 方法接受一个 promise 对象的数组作为参数
- 返回值: promise 对象,其状态为 FULFILLED,值为一个数组,数组中的每个元素都是一个对象,表示每个 promise 对象的状态和值
1 static allSettled(promiseArr) {
2 if (typeof promiseArr[Symbol.iterator] !== 'function') {
3 throw new Error('参数必须是可迭代对象')
4 }
5 return new MyPromise((resolve, reject) => {
6 let result = []
7 let count = 0
8 for (let i = 0; i < promiseArr.length; i++) {
9 promiseArr[i].then(res => {
10 result[i] = { status: 'fulfilled', value: res }
11 }, err => {
12 result[i] = { status: 'rejected', reason: err }
13 })
14 }
15 })
16 }
9.race 方法
- race 方法接受一个 promise 对象的数组作为参数
- 返回值:返回最先执行完的 promise 对象的结果, 无论成功、失败
1static race(promiseArr) {
2 if (typeof promiseArr[Symbol.iterator] !== 'function') {
3 throw new Error('参数必须是可迭代对象')
4 }
5 return new MyPromise((resolve, reject) => {
6 for (let i = 0; i < promiseArr.length; i++) {
7 promiseArr[i].then(res => {
8 resolve(res)
9 }, err => {
10 reject(err)
11 })
12 }
13 })
14 }
10. any
- any 方法接受一个 promise 对象的数组作为参数
- 返回值:返回最先成功 promise 对象的结果, 如果全部失败则返回一个失败的 promise 对象
1 static any(promiseArr) {
2 if (typeof promiseArr[Symbol.iterator] !== 'function') {
3 throw new Error('参数必须是可迭代对象')
4 }
5 return new MyPromise(async(resolve, reject) => {
6 const result = []
7 for (let i = 0; i < promiseArr.length; i++) {
8 try {
9 const res = await promiseArr[i]
10 resolve(res)
11 } catch (error) {
12 result[i] = { status: 'rejected', reason: error }
13 if (i === promiseArr.length - 1) {
14 reject(result)
15 }
16 }
17 }
18
19 })
20 }
完整代码
1const PENDING = 'pending'
2const FULFILLED = 'fulfilled'
3const REJECTED = 'rejected'
4
5class MyPromise {
6 #status = PENDING;
7 #reason = null;
8 #handlers = [];
9
10 constructor(executor) {
11 const resolve = (reason) => {
12 this.#changeState(FULFILLED, reason)
13 }
14 const reject = (reason) => {
15 this.#changeState(REJECTED, reason)
16 }
17 try {
18 executor(resolve, reject);
19 } catch (error) {
20 reject(error);
21 }
22 }
23 then(onFulfilled, onRejected) {
24 return new MyPromise((resolve, reject) => {
25 this.#handlers.push({
26 onFulfilled,
27 onRejected,
28 resolve,
29 reject
30 });
31 this.#run();
32 });
33
34 }
35
36 catch(onRejected) {
37 return this.then(null, onRejected);
38 }
39 finally(onFinally) {
40 return this.then(
41 value => MyPromise.resolve(onFinally()).then(() => value),
42 reason => MyPromise.resolve(onFinally()).then(() => {
43 throw reason
44 })
45 )
46 }
47
48 static reject(reason) {
49 return new MyPromise((resolve, reject) => {
50 reject(reason)
51 })
52 }
53
54 static resolve(value) {
55 if (value instanceof MyPromise) return value
56 return new MyPromise((resolve, reject) => {
57 resolve(value)
58 })
59 }
60
61 static all(promiseArr) {
62 if (typeof promiseArr[Symbol.iterator] !== 'function') {
63 throw new Error('参数必须是可迭代对象')
64 }
65 return new MyPromise((resolve, reject) => {
66 let result = []
67 let count = 0
68 for (let i = 0; i < promiseArr.length; i++) {
69 promiseArr[i].then(res => {
70 result[i] = res
71 count++
72 if (count === promiseArr.length) {
73 resolve(result)
74 }
75 }, err => {
76 reject(err)
77 })
78 }
79 })
80 }
81
82 static race(promiseArr) {
83 if (typeof promiseArr[Symbol.iterator] !== 'function') {
84 throw new Error('参数必须是可迭代对象')
85 }
86 return new MyPromise((resolve, reject) => {
87 for (let i = 0; i < promiseArr.length; i++) {
88 promiseArr[i].then(res => {
89 resolve(res)
90 }, err => {
91 reject(err)
92 })
93 }
94 })
95 }
96
97 static allSettled(promiseArr) {
98 if (typeof promiseArr[Symbol.iterator] !== 'function') {
99 throw new Error('参数必须是可迭代对象')
100 }
101 return new MyPromise((resolve, reject) => {
102 let result = []
103 for (let i = 0; i < promiseArr.length; i++) {
104 promiseArr[i].then(res => {
105 result[i] = { status: 'fulfilled', value: res }
106 }, err => {
107 result[i] = { status: 'rejected', reason: err }
108 })
109 }
110 resolve(result)
111 })
112 }
113
114 static any(promiseArr) {
115 if (typeof promiseArr[Symbol.iterator] !== 'function') {
116 throw new Error('参数必须是可迭代对象')
117 }
118 return new MyPromise(async (resolve, reject) => {
119 const result = []
120 for (let i = 0; i < promiseArr.length; i++) {
121 try {
122 const res = await promiseArr[i]
123 resolve(res)
124 } catch (error) {
125 result[i] = { status: 'rejected', reason: error }
126 if (i === promiseArr.length - 1) {
127 reject(result)
128 }
129 }
130 }
131
132 })
133
134 }
135
136
137 * promise 状态发生改变时:记录状态及结果,并执行run函数
138 * @param {*} state 状态
139 * @param {*} reason 结果
140 * @returns
141 */
142 #changeState(state, reason) {
143 if (this.#status !== PENDING) return;
144 this.#status = state;
145 this.#reason = reason;
146 this.#run();
147 }
148
149 * run函数:辅助then函数返回的promise对象有结果时,
150 * 遍历执行所有onFulfilled、onRejected 并把结果传递给下一个promise对象
151 * @returns
152 */
153 #run() {
154 if (this.#status === PENDING) return;
155 while (this.#handlers.length) {
156 const { onFulfilled, onRejected, resolve, reject } = this.#handlers.shift();
157 let fn = this.#status === FULFILLED ? onFulfilled : onRejected;
158 this.#runFn(fn, resolve, reject);
159 }
160 }
161
162 * setTimeout执行模拟微任务的执行环境
163 * @param {*} fn onFulfilled | onRejected
164 * @param {*} resolve 通过resolve传递给下一个promise对象
165 * @param {*} reject
166 *
167 */
168 #runFn(fn, resolve, reject) {
169 setTimeout(() => {
170 if (typeof fn !== 'function') {
171 let settled = this.#status === FULFILLED ? resolve : reject;
172 settled(this.#reason)
173 return
174 }
175 try {
176 const res = fn(this.#reason);
177
178 resolve(res)
179 } catch (error) {
180 reject(error)
181 }
182 }, 0)
183 }
184}
个人笔记记录 2021 ~ 2025