-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPromise.js
131 lines (120 loc) · 2.84 KB
/
Promise.js
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
/*
Promise 实现
Promise A+ 规定回调为微任务,这里用 setTimeout 模拟
*/
/* 三种状态 */
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
/* 构造函数 */
function MyPromise(executor) {
let self = this; //缓存 promise 实例
self.value = null;
self.error = null;
self.status = PENDING;
self.onFulfilledCallbacks = [];
self.onRejectedCallbacks = [];
const resolve = value => {
if (value instanceof MyPromise) {
return value.then(resolve, reject);
}
setTimeout(() => {
if (self.status !== PENDING) return;
self.status = FULFILLED;
self.value = value;
self.onFulfilledCallbacks.forEach(callback => void callback(value));
}, 0);
};
const reject = error => {
setTimeout(() => {
if (self.status !== PENDING) return;
self.status = REJECTED;
self.error = error;
self.onRejectedCallbacks.forEach(callback => void callback(error));
}, 0);
};
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
/**
* then
* @param {function} onFulfilled 返回成功结果时的处理函数
* @param {function} onRejected 返回失败结果时的处理函数
* @returns {Promise}返回一个新的 Promise 实例
*/
MyPromise.prototype.then = function (onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected =
typeof onRejected === 'function'
? onRejected
: error => {
throw error;
};
const self = this;
return new MyPromise((resolve, reject) => {
let fulfilled = () => {
try {
const result = onFulfilled(self.value);
return result instanceof MyPromise
? result.then(resolve, reject)
: resolve(result);
} catch (e) {
reject(e);
}
};
let rejected = () => {
try {
const result = onRejected(self.error);
return result instanceof MyPromise
? result.then(resolve, reject)
: reject(result);
} catch (e) {
reject(e);
}
};
switch (self.status) {
case PENDING:
self.onFulfilledCallbacks.push(fulfilled);
self.onRejectedCallbacks.push(rejected);
break;
case FULFILLED:
fulfilled();
break;
case REJECTED:
rejected();
break;
}
});
};
/**
* catch 方法 其实就是 then 的语法糖
* @param {function} onRejected 处理错误
* @returns {Promise}
*/
MyPromise.prototype.catch = function (onRejected) {
return this.then(null, onRejected);
};
/* test */
let f = a => {
return new MyPromise((resolve, reject) => {
resolve(a);
});
};
const t = f(1)
.then(v => {
console.log(v); //1
return f(2);
})
.then(v => {
console.log(v); //2
return 9;
})
.then(v => {
console.log(v); //9
throw new Error('ee');
})
.catch(e => console.log(e)); //[Error: ee]