Roll your own Promise(3)

[MUSINGS]
今天又是学会拒绝的一课,拒绝了晚饭邀约,嘻嘻,回家洗完澡吃了宵夜直接变废人,早起写race和all写了快一个小时。总算倒腾完了,先贴出来吧

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
type State = "pending" | "fulfilled" | "rejected";
class PromiseI {
private state: State;
private fnList: Function[];
private val: any;
constructor(executer: (acc, rej) => void) {
this.state = "pending";
this.fnList = [];
executer(this.resolve.bind(this), this.reject.bind(this))
}

resolve(val: string) {
if (this.state == "pending") {
this.val = val;
this.state = "fulfilled";
console.log("this is resolve:", val);
if (this.fnList.length > 0) {
for (const fn of this.fnList) {
queueMicrotask(() => fn());
}
}
} else {
console.error("can't update the state");
}
}

reject(val: string) {
if (this.state == "pending") {
this.state = "rejected";
this.val = val;
console.log("this is reject:", val);
if (this.fnList.length > 0) {
for (const fn of this.fnList) {
queueMicrotask(() => fn());
}
}
} else {
console.error("can't update the state");
}
}

then(onFulfilled: Function, onRejected?: Function) {
return new PromiseI((resolve, reject) => {
const run = () => {
queueMicrotask(() => {
if (this.state == 'fulfilled') {
try {
const x = onFulfilled(this.val);
resolve(x);
}
catch (e) {
reject(e);
}
}
else if (this.state == 'rejected' && onRejected) {
try {
const x = onRejected(this.val);
resolve(x);
} catch (e) {
reject(e)
}
}
})
}
if (this.state == "pending") {
this.fnList.push(run);
} else {
run();
}
});
}

// static resolve(fn: Function): {

// }

static all(fnList: PromiseI[]) {
return new PromiseI((resolve, reject) => {
let resultList: any = [];
fnList.forEach((fn, i) => {
fn.then(//使用异步来获取
(val) => {
if (val) {
resultList[i] = val;
}
if (resultList.length == fnList.length) {//根据长度判断
resolve(resultList);
}
},
(err) => {
reject(err);
})
})

})
}
static race(promisList: PromiseI[]) {
let flag = false;
return new PromiseI(
(resolve, reject) => {
for (const pro of promisList) {
pro.then(
(val) => {
if (flag) return; //注意promise本身的逻辑,需要在任何一个promise settle的时候立刻返回,所以需要用标志位控制
resolve(val);
flag = true;
}, err => {
reject(err);
}
)
}
}

)
}

}
//test case

// let promise = new PromiseI((resolve, reject) => {
// resolve("success");
// });
// promise.then((res) => {
// console.log("then", res);
// return "yes"
// });
// promise.then((res) => {
// console.log("then", res);
// return "lala"
// });
// setTimeout(() => console.log("timeout 0"), 0);

PromiseI.race([
new PromiseI((resolve) => setTimeout(() => { resolve(111) }, 1000)),
new PromiseI((resolve) => resolve(222))
]
).then(
(arg) => { console.log("success", arg) },
erro => console.log("failed")
)


写于 08:32, Sun, Oct 5, 2025 (GMT+8)