自己写一个Promise A+

自己手动写一个Promise A+代码, 实现了基本功能(包括then/catch/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
class Promise {
// constructor
constructor(executorCallBack) {
this.status = "pending";
this.value = undefined;
this.fulfilledAry = [];
this.rejectedAry = [];

let resolveFn = result => {
let timer = setTimeout(() => {
clearTimeout(timer);
if (!this.status === "pending") {
return;
}
this.status = "fulfilled";
this.value = result;
this.fulfilledAry.forEach(item => item(this.value));
}, 0);
};
let rejectFn = reason => {
let timer = setTimeout(() => {
clearTimeout(timer);
if (!this.status === "pending") {
return;
}
this.status = "rejected";
this.value = reason;
this.fulfilledAry.forEach(item => item(this.value));
}, 0);
};

try {
executorCallBack(resolveFn, rejectFn);
} catch (err) {
rejectFn(err);
}
}

// methods
then(fulfilledCallBack, rejectedCallBack) {
typeof fulfilledCallBack !== "function"
? (fulfilledCallBack = result => result)
: null;
typeof rejectedCallBack !== "function"
? (rejectedCallBack = reason => {
throw new Error(reason instanceof Error ? reason.message : reason);
})
: null;
return new Promise((resolve, reject) => {
this.fulfilledAry.push(() => {
try {
let x = fulfilledCallBack(this.value);
x instanceof Promise ? x.then(resolve, reject) : resolve(x);
} catch (err) {
reject(err);
}
});
this.rejectedAry.push(() => {
try {
let x = rejectedCallBack(this.value);
x instanceof Promise ? x.then(resolve, reject) : resove(x);
} catch (err) {
reject(err);
}
});
});
}

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

static all(promiseAry = []) {
// 用Promise.all() 来执行
return new Promise((resolve, reject) => {
let successCounter = 0,
result = [];
for (let i = 0; i < promiseAry.length; i++) {
// promiseAry[i] 每一个处理的promise实例
promiseAry[i].then(val => {
successCounter++;
result[i] = val;
if (successCounter === promiseAry.length) {
resolve(result);
}
}, reject);
}
});
}
}

module.exports = Promise;