Roll your own Promise(2)

[Musings]
在连江的第二天,感觉不错,一天没喝酒很舒服,lol
靠海吃海,全是新鲜的海鲜,继续写Promise,应该每天先花时间写算法和设计模式的,然后再去开启一天的生活,不然很多时间都被其他东西占有了,不合理。重要的事得先行

Now, let’s come to the coding part, share the code snippet first

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
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();
}
});
}
}

//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"
});

Here are some points I want to hightlight:

  1. The constructor part should clear with the bind
  2. Resolve and Reject function should pluge the function list and use queueMicrotask to handle the logic
  3. Then function need to use method chaining, and the value should be transfer to the next promise.

It’s a little complicated to implemente for Promise, but keep ongoing… I trust I am doing the right things.