-
Notifications
You must be signed in to change notification settings - Fork 0
/
promise-A+.js
119 lines (100 loc) · 4.68 KB
/
promise-A+.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
//promise本质是个类
class Promise {
constructor(excutorCB) {
this.status = 'pending';
this.value = undefined;
this.fulfilledContainer = []; //存成功要执行的方法
this.rejectedContainer = []; //存失败要执行的方法
//执行excutorCB (增加异常捕获)
//resolve 代表成功
let resolve = (result) => {
let timer = setTimeout(() => { //加入定时器使方法变为异步,这样就可以在then执行之后再执行
clearTimeout(timer); //销毁定时器
if (this.status !== 'pending') return;
this.status = 'fulfilled';
this.value = result;
this.fulfilledContainer.forEach(item => {
item(this.value); //遍历then中的方法,并把result传给then
})
}, 0);
};
//reject 代表失败
let reject = (reason) => {
let timer = setTimeout(() => { //加入定时器使方法变为异步,这样就可以在then执行之后再执行
clearTimeout(timer); //销毁定时器
if (this.status !== 'pending') return;
this.status = 'rejected';
this.value = reason;
this.rejectedContainer.forEach(item => {
item(this.value); //遍历then中的方法,并把reason传给then
})
}, 0);
};
//异常捕获
try {
excutorCB(resolve, reject);
} catch (err) {
//有异常信息就按照rejected状态处理
reject(err);
}
// excutorCB(resolve, reject);
}
then(fulfilledCB, rejectedCB) {
if (typeof fulfilledCB !== 'function') { //如果不传成功的回调
fulfilledCB = result => result //简写,相当于 result => { return result }
}
if (typeof rejectedCB !== 'function') { //如果不传错误的回调
rejectedCB = reason => {
throw new Error(reason instanceof Error ? reason.message : reason); //thorw不支持简写
}
}
return new Promise((resolve, reject) => { //实现then的链式写法
this.fulfilledContainer.push((val) => {
try {
let x = fulfilledCB(val);
// console.log(val === this.value);
if (x instanceof Promise) { //检查x是不是Promise实例
x.then(resolve, reject); //如果是Promise的实例,那么Promise实例本身存在成功与失败,成功走resolve,失败走reject
return;
}
resolve(x); //如果不是Promise实例,直接返回值就可以了,下个then直接就接收这个值,不存在失败
} catch (err) {
reject(err);
}
});
this.rejectedContainer.push((val) => {
try {
let x = rejectedCB(val);
if (x instanceof Promise) { //检查x是不是Promise实例
x.then(resolve, reject); //如果是Promise的实例,那么Promise实例本身存在成功与失败,成功走resolve,失败走reject
return;
}
resolve(x); //如果不是Promise实例,直接返回值就可以了,下个then直接就接收这个值,不存在失败
} catch (err) {
reject(err);
}
});
})
// this.fulfilledContainer.push(fulfilledCB);
// this.rejectedContainer.push(rejectedCB);
}
catch(rejectedCB) { //catch相当于then方法第一个参数不传,只穿第二个
return this.then(null, rejectedCB);
}
static all(promiseArr = []) { //static:把Promise当做对象添加私有属性,用Promise.all来执行
return new Promise((resolve, reject) => {
let index = 0, //记录成功几个
resultArr = []; //把成功的结果放入result中
promiseArr.forEach((item, value) => {
item.then((result) => {
index++;
resultArr[value] = result;
if (index === promiseArr.length) { //当index与 promiseArr.length 长度相等的时候
resolve(resultArr);
}
}, reject);
});
})
}
}
module.exports = Promise;