Promise/A+

Promise/A

Promise/A+可以用来检验手写的Promise时候合格,一共872个样例。

如何使用

1
2
yarn init
yarn add -D promises-aplus-tests
  • 初始化并安装npm包(笔者习惯用yarn)。
  • 把自己的写好的Promise对象放入一个文件,命名为TestPromise.js
  • 根据github上的描述增加一个静态方法,并用commonJS的方式导出promise类,
1
2
3
4
5
6
7
8
9
10
11
myPromise.deferred = function() {
var result = {};
result.promise = new myPromise(function(resolve, reject) {
result.resolve = resolve;
result.reject = reject;
});

return result;
};

module.exports = myPromise;

如何手写

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
192
193
194
195
196
197
198
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

class myPromise {
constructor(fn) {
// 状态
this.state = PENDING;
// 终值
this.value = undefined;
// 拒因
this.reason = undefined;
// 执行回调队列
this.onFulfilledCallbacks = [];
// 拒绝回调队列
this.onRejectedCallbacks = [];

// 执行的方法
const resolve = (value) => {
// 需要异步,这里使用宏任务
setTimeout(() => {
if (this.state === PENDING) {
this.state = FULFILLED;
this.value = value;
// 等待态->执行态
// 需要调用执行回调队列的所有方法
this.onFulfilledCallbacks.forEach((f) => f(this.value));
}
});
};

// 拒绝的方法
const reject = (reason) => {
// 需要异步,这里使用宏任务
setTimeout(() => {
if (this.state === PENDING) {
this.state = REJECTED;
this.reason = reason;
// 等待态->拒绝态
// 需要调用拒绝回调队列的所有方法
this.onRejectedCallbacks.forEach((f) => f(this.reason));
}
});
};

// 如果报错,就调用拒绝方法
try {
fn(resolve, reject);
} catch (e) {
reject(e);
}
}

then(onFulfilled, onRejected) {
let promise;

const isFunFulfilled = typeof onFulfilled === "function";
const isFunRejected = typeof onRejected === "function";

if (this.state === PENDING) {
promise = new Promise((resolve, reject) => {
this.onFulfilledCallbacks.push((value) => {
try {
// 是否函数判断、写到里面一层
if (isFunFulfilled) {
const x = onFulfilled(value);
ResolutionProcedure(promise, x, resolve, reject);
} else {
// 在构造函数里,如果状态完成或失败了,会执行相应的回调队列。
// 在这个方法内部,肯定是状态完成了,才执行的。
// 而且value也是this.value
resolve(value);
}
} catch (e) {
reject(e);
}
});

this.onRejectedCallbacks.push((reason) => {
try {
// 与上面同理
if (isFunRejected) {
const x = onRejected(reason);
ResolutionProcedure(promise, x, resolve, reject);
} else {
reject(reason);
}
} catch (e) {
reject(e);
}
});
});
}

if (this.state === FULFILLED) {
promise = new Promise((resolve, reject) => {
setTimeout(() => {
try {
// 是否函数判断、写到里面一层
if (isFunFulfilled) {
const x = onFulfilled(this.value);
ResolutionProcedure(promise, x, resolve, reject);
} else {
// 看看45行,状态是完成的了
resolve(this.value);
}
} catch (e) {
reject(e);
}
});
});
}

if (this.state === REJECTED) {
promise = new Promise((resolve, reject) => {
setTimeout(() => {
try {
// 与上面同理
if (isFunRejected) {
const x = onRejected(this.reason);
ResolutionProcedure(promise, x, resolve, reject);
} else {
reject(this.reason);
}
} catch (e) {
reject(e);
}
});
});
}

return promise;
}
}

function ResolutionProcedure(promise, x, resolve, reject) {
if (promise === x) {
reject(new TypeError("循环引用"));
return;
}

if (x instanceof myPromise) {
switch (x.state) {
case PENDING:
x.then((value) => {
ResolutionProcedure(promise, value, resolve, reject);
}, reject);
break;
case FULFILLED:
resolve(x.value);
break;
case REJECTED:
reject(x.reason);
break;
}
} else if (x && ["object", "function"].includes(typeof x)) {
let firstRun = false;
try {
const then = x.then;

if (typeof then === "function") {
const resolvePromise = (y) => {
if (firstRun) return;
firstRun = true;
ResolutionProcedure(promise, y, resolve, reject);
};

const rejectPromise = (r) => {
if (firstRun) return;
firstRun = true;
reject(r);
};

then.call(x, resolvePromise, rejectPromise);
} else {
resolve(x); // 2.3.3.4 如果then不是函数,用x来完成promise
}
} catch (e) {
if (firstRun) return;
firstRun = true;
reject(e);
}
} else {
resolve(x); // 2.3.4 如果x不是对象或者函数,用x来完成promise
}
}

myPromise.deferred = function() {
var result = {};
result.promise = new myPromise(function(resolve, reject) {
result.resolve = resolve;
result.reject = reject;
});

return result;
};

module.exports = myPromise;

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!