Promise
Promise的A+标准
- 术语
- promise:是一个拥有 then 方法的对象或函数,其行为符合本规范
- thenable:是一个定义了 then 方法的对象或函数。这个主要是用来兼容一些老的Promise实现,只要一个Promise实现是thenable,也就是拥有then方法的,就可以跟Promises/A+兼容。
- value:指reslove出来的值,可以是任何合法的JS值(包括 undefined , thenable 和 promise等)
- exception:异常,在Promise里面用throw抛出来的值
- reason:拒绝原因,是reject里面传的参数,表示reject的原因
- Promise状态
- pending: 一个promise在resolve或者reject前就处于这个状态。
- fulfilled: 一个promise被resolve后就处于fulfilled状态,这个状态不能再改变,而且必须拥有一个不可变的值(value)。
- rejected: 一个promise被reject后就处于rejected状态,这个状态也不能再改变,而且必须拥有一个不可变(引用不变)的拒绝原因(reason)。
- then方法
- 一个promise必须拥有一个then方法来访问他的值或者拒绝原因。then方法有两个参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14promise.then(onFulfilled, onRejected)
//onFulfilled 和 onRejected 都是可选参数。
//如果 onFulfilled 不是函数,其必须被忽略
//如果 onRejected 不是函数,其必须被忽略
//如果 onFulfilled 是函数:
//当 promise 执行结束后其必须被调用,其第一个参数为 promise 的终值value
//在 promise 执行结束前其不可被调用
//其调用次数不可超过一次
//如果 onRejected 是函数:
//当 promise 被拒绝执行后其必须被调用,其第一个参数为 promise 的拒因reason
//在 promise 被拒绝执行前其不可被调用
//其调用次数不可超过一次
- 一个promise必须拥有一个then方法来访问他的值或者拒绝原因。then方法有两个参数:
- 多次调用
- then 方法可以被同一个 promise 调用多次
- 当 promise 成功执行时,所有 onFulfilled 需按照其注册顺序依次回调
- 当 promise 被拒绝执行时,所有的 onRejected 需按照其注册顺序依次回调
返回
then 方法必须返回一个 promise对象。
promise2 = promise1.then(onFulfilled, onRejected);
- 如果 onFulfilled 或者 onRejected 返回一个值 x ,则运行 Promise 解决过程:[[Resolve]](promise2, x)
- 如果 onFulfilled 或者 onRejected 抛出一个异常 e ,则 promise2 必须拒绝执行,并返回拒因 e
- 如果 onFulfilled 不是函数且 promise1 成功执行, promise2 必须成功执行并返回相同的值
- 如果 onRejected 不是函数且 promise1 拒绝执行, promise2 必须拒绝执行并返回相同的据因
- 剩下的标准在代码里有所体现
- 术语
手写A+标准的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
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//872 passing!
var PENDING = 'pending';
var FULFILLED = 'fulfilled';
var REJECTED = 'rejected';
function MyPromise(fn) {
this.status = PENDING; //初始状态为pending
this.value = null; //初始value为null
this.reason = null; //初始reason为null
this.onFulfilledCallbacks = []; //onFulfilled事件中心
this.onRejectedCallbacks = []; //onRejected事件中心
var that = this; //这个that是MyPromise中的this
// 根据规范
//resolve把status改为fulfilled,
//reject把status改为rejected
//resolve相当于发布一个成功事件
function resolve(value) {
if (that.status === PENDING) {
that.status = FULFILLED;
that.value = value;
that.onFulfilledCallbacks.map((callback) => callback(that.value));
}
}
//rejected相当于发布一个失败事件
function rejected(reason) {
if (that.status === PENDING) {
that.status = REJECTED;
that.reason = reason;
that.onRejectedCallbacks.map((callback) => callback(that.reason));
}
}
//如果有错误,马上捕获
try {
fn(resolve, rejected);
} catch (err) {
rejected(err);
}
}
function resolvePromise(promise, x, resolve, reject) {
//如果promise和x指向同一对象,抛出TypeError错误,并拒绝执行
if (promise === x)
return reject(new TypeError('resolvePromise: promise and x are the same!'));
if (x instanceof MyPromise) {
//如果x也是一个promise,那么继续执行,获取最终状态
x.then(function (res) {
resolvePromise(promise, res, resolve, reject);
}, reject);
} else if (typeof x === 'object' || typeof x === 'function') {
//如果x不是一个promise
if (x === null) {
return resolve(x);
}
try {
var then = x.then;
} catch (err) {
return reject(err);
}
//如果then是函数
if (typeof then === 'function') {
var called = false;
try {
then.call(
x,
function (y) {
if (called) return;
called = true;
resolvePromise(promise, y, resolve, reject);
},
function (y) {
if (called) return;
called = true;
reject(y);
}
);
} catch (err) {
//调用then方法抛出了异常
//如果called已经为true,则不需要管then的执行情况,直接忽略
if (called) return;
reject(err);
}
} else {
resolve(x);
}
} else {
resolve(x);
}
}
//then方法可以链式调用
//a+规范中规定API为promise.then(onFulfilled, onRejected)
//then方法放在prototype上
MyPromise.prototype.then = function (onFulfilled, onRejected) {
var that = this;
//a+规范约定
//若onFulfilled不是函数,则忽略
//若onRejected不是函数,则忽略
//这里的忽略不是什么都不做
//对于onFulfilled来说,我们提供一个函数,将value原封不懂返回
//对于onRejected来说,throw一个ERROR出去
var realOnFulfilled = onFulfilled;
if (typeof onFulfilled !== 'function') {
realOnFulfilled = function (value) {
return value;
};
}
var realOnRejected = onRejected;
if (typeof onRejected !== 'function') {
realOnRejected = function (err) {
throw err;
};
}
//a+规范规定
//then方法必须返回一个Promise对象
//如果 onFulfilled
//或者 onRejected 抛出一个异常 e ,则 promise2 必须拒绝执行,并返回拒因 e
if (this.status === PENDING) {
//这里有订阅发布模式的思想
var promise2 = new MyPromise(function (resolve, reject) {
that.onFulfilledCallbacks.push(function () {
setTimeout(function () {
try {
var x = realOnFulfilled(that.value);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
}); //注册事件
that.onRejectedCallbacks.push(function () {
setTimeout(function () {
try {
var x = realOnRejected(that.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
}); //注册事件
});
return promise2;
}
//如果 onFulfilled 不是函数且 promise1 成功执行, promise2 必须成功执行并返回相同的值
if (this.status === FULFILLED) {
var promise2 = new MyPromise(function (resolve, reject) {
setTimeout(function () {
try {
if (typeof onFulfilled !== 'function') {
resolve(that.value);
} else {
var x = realOnFulfilled(that.value);
resolvePromise(promise2, x, resolve, reject);
}
} catch (err) {
reject(err);
}
}, 0);
});
return promise2;
}
//如果onRejected 不是函数且 promise1 拒绝执行, promise2必须拒绝并返回相同的拒因
//如果onRejected 是函数且promise1拒绝执行, promise2应该resolve
if (this.status === REJECTED) {
var promise2 = new MyPromise(function (resolve, reject) {
setTimeout(function () {
try {
if (typeof onRejected !== 'function') {
reject(that.reason);
} else {
var x = realOnRejected(that.reason);
resolvePromise(promise2, x, resolve, reject);
}
} catch (err) {
reject(err);
}
}, 0);
});
return promise2;
}
};