-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathES6_Promise.js
More file actions
191 lines (182 loc) · 6.75 KB
/
Copy pathES6_Promise.js
File metadata and controls
191 lines (182 loc) · 6.75 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
class Promise {
constructor(executer) {
this.PromiseState = 'pending';//默认应该是等待
this.PromiseResult = undefined;
//定义一个属性来存放then函数的回调们。
this.callbacks = [];
//参数executer是一个立即调用的函数
//且该函数还接收两个参数,分别是两个函数
const success = (data) => {
//这是resolve对应的回调
//状态改变后就不能再变,加个判断
if (this.PromiseState !== 'pending') return;
//1.改变对象的状态:pending=>resolved
this.PromiseState = 'resolved';
//2.改变对象的结果值
this.PromiseResult = data;
//3.如果是异步,要在以上步骤结束后,执行对应的回调
// if(this.callback.onResolved){
// this.callback.onResolved(data);
// }
if (this.callbacks.length != 0) {
setTimeout(() => {
this.callbacks.forEach(item => {
item.onResolved();
})
});
}
}
const fail = (data) => {
//这是reject对应的回调
//状态改变后就不能再变,加个判断
if (this.PromiseState !== 'pending') return;
//1.改变对象的状态:pending=>resolved
this.PromiseState = 'rejected';
//2.改变对象的结果值
this.PromiseResult = data;
//3.如果是异步,要在以上步骤结束后,执行对应的回调
// if(this.callback.onRejected) {
// this.callback.onRejected(data);
// }
if (this.callbacks.length != 0) {
setTimeout(() => {
this.callbacks.forEach(item => {
item.onRejected();
})
});
}
}
try {
executer(success, fail);
} catch (data) {
//如果抛出错误,那么就执行下面的代码
fail(data);
}
}
//1.then方法的封装
then(onResolved, onRejected) {
//判断第二个回调是否存在,没有就写个默认的
if (typeof onRejected !== 'function') {
onRejected = err => {
console.log('第二个默认回调执行');
throw err;//一直往后找错误的回调
}
}
//如果不写第一个回调,也能实现值的传递
if (typeof onResolved !== 'function') {
onResolved = res => {
console.log('第一个默认回调执行');
return res;
};
}
//执行then方法返回的还是Promise
return new Promise((resolve, reject) => {
//公共的改变返回Promise状态的方法封装起来
let changeState = (name) => {
try {
const outcome = name(this.PromiseResult);
//判断回调返回结果是否是Promise类型
if (outcome instanceof Promise) {
//Promise类型的数据,返回状态要和它一致
outcome.then(res => {
//如果是成功的Promise,那一定会走这个回调
resolve(res);
}, err => {
//如果是失败的Promise,那一定会走这个回调
reject(err);
})
} else {
//非Promise类型,返回成功的Promise
resolve(outcome);
}
} catch (e) {
reject(e);
}
}
//判断同步任务下走哪个回调
if (this.PromiseState === 'resolved') {
setTimeout(() => {
changeState(onResolved);
});
//如果抛出错误,不用再另外写try-catch,封装时写过了
//所以任何Promise实例执行器函数出现错误,都可以直接捕获
}
if (this.PromiseState === 'rejected') {
setTimeout(() => {
changeState(onRejected);
});
}
//如果是异步任务(先指定回调再改变状态再执行回调)
if (this.PromiseState === 'pending') {
//把回调存到该实例的属性上
// this.callback.onResolved = onResolved;
// this.callback.onRejected = onRejected;
this.callbacks.push({
onResolved: () => {
changeState(onResolved);
},
onRejected: () => {
changeState(onRejected);
}
})
}
})
}
//2.catch方法的封装
catch(onRejected) {
return this.then(undefined, onRejected);
}
//不是实例身上的方法,加上static关键字
//3.resolve方法封装
static resolve(data) {
return new Promise((resolve, reject) => {
if (data instanceof Promise) {
data.then(res => {
resolve(res);
}, err => {
reject(err);
})
} else {
resolve(data);
}
})
}
//4.reject方法封装
static reject(data) {
return new Promise((resolve, reject) => {
reject(data);
})
}
//5.all方法封装
static all(promiseArr) {
return new Promise((resolve, reject) => {
let flag = true; //判断是否所有都成功
let arr = []; //存储成功的结果
for (let i = 0; i < promiseArr.length; i++) {
promiseArr[i].then(res => {
// arr.push(res); //这么写可能会由于异步出现顺序问题
arr[i] = res; //这么写没事,是let的块级作用域效果
}, err => {
reject(err);
flag = false;
})
}
//循环结束后,判断是否所有Promise都是成功的
if (flag) {
resolve(arr);
}
})
}
//6.race方法封装
static race(promiseArr) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promiseArr.length; i++) {
promiseArr[i].then(res => {
resolve(res);
}, err => {
reject(err);
})
}
})
}
}