手写实现一个Promise

Promise的定义

Promise是ES6提供的一个用于解决异步回调地狱的语法,标准的定义如下:

  • 有三种状态:pending,fulfilled,rejected;
  • 构造函数传入一个执行函数,该函数有两个参数,resolve,成功的回调,reject,失败的回调;
  • 包含一个then函数,支持链式调用;
  • 包含一个catch函数,用户捕获promise的异常

具体实现

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
const stateMap = {
PENDING: 'pending',
FULFILLED: 'fulfilled',
REJECTED: 'rejected',
}

class MyPromise {
constructor(executor) {
this.id = id;
this.state = stateMap.PENDING;
this.value = undefined;
this.reason = undefined;
this.fulfillCallbackList = [];
this.rejectCallbackList = [];

const resolve = (value) => {
if (this.state !== stateMap.PENDING) return;
this.state = stateMap.FULFILLED;
this.value = value;
this.fulfillCallbackList.forEach((callback) => callback(this.value));
}
const reject = (reason) => {
if (this.state !== stateMap.PENDING) return;
this.state = stateMap.REJECTED;
this.reason = reason;
this.rejectCallbackList.forEach((callback) => callback(this.reason));
}

try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}

then(onFulFill, onReject) {
const thenPromise = new MyPromise((resolve, reject) => {
if (this.state === stateMap.FULFILLED) {
try {
const value = onFulFill(this.value);
resolve(value);
} catch (error) {
reject(error);
}
} else if (this.state === stateMap.REJECTED) {
try {
const reason = onReject(this.reason);
reject(reason);
} catch (error) {
reject(error);
}
} else {
this.fulfillCallbackList.push(() => {
try {
const value = onFulFill(this.value);
resolve(value);
} catch (error) {
reject(error);
}
});

this.rejectCallbackList.push(() => {
try {
const reason = onReject(this.reason);
resolve(reason);
} catch (error) {
reject(error);
}
})
}
});

return thenPromise;
}

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

function test(PromiseType = Promise) {
const promise = new PromiseType((resolve, reject) => {
setTimeout(() => {
const num = Math.random() * 10;
if (num < 5) {
resolve(num);
} else {
reject('num is not less than 5');
}
}, 3000);
});

promise.then((value) => {
console.log('fulfill-1', value);
value = `then1-${value}`;
},(reason) => {
console.log('reject-1', reason);
reason = `then1-${reason}`;
return reason;
}).then((value)=> {
console.log('fulfill-2', value);
value = `then2-${value}`;
}, (reason) => {
console.log('reject-2', reason);
reason = `then2-${reason}`;
}).then((value) => {
console.log('promise', promise, value);
});
}

test(Promise);

test(MyPromise);

联系我