ES6Promise
實現一個符合 Promise/A+ 規範的ES6寫法的Promise,並實現 resolve、reject、all、race等靜態方法。
Constructor(構造器)
- 作用:從建構函式
Promise
來建立一個新建新promise
物件,可以使用new
來呼叫Promise
的構造器來進行例項化 - 接收一個回撥函式
executor
- 狀態
- 如果是
pending
狀態,則promise
:- 可以轉換到
fulfilled
或rejected
狀態。
- 可以轉換到
- 如果是
fulfilled
狀態,則promise
:- 不能轉換成任何其它狀態。
- 必須有一個值,且這個值不能被改變。
- 如果是
rejected
狀態,則promise
可以:- 不能轉換成任何其它狀態。
- 如果是
- resolve
promise
的狀態是fulfilled
異常是的處理函式- 接收
value
引數- 如果是
promise
,執行then
。 - 如果不是
promise
,把value
做為引數傳給onFulfilledCallbacks
裡的每個函式。
- 如果是
- reject
promise
的狀態是rejected
異常是的處理函式- 接收
reason
引數,把reason
做為引數傳給onRejectedCallbacks
裡的每個函式。
- 執行
executor
,如果有異常,拋給reject
constructor(executor) {
if (typeof executor !== 'function') {
throw new TypeError('Promise resolver ' + executor + ' is not a function');
}
let self = this
this.status = 'pending'
this.value = undefined
this.reason = undefined
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
function resolve (value) {
if (value instanceof ES6Promise) {
return value.then(resolve, reject);
}
if (self.status === 'pending') {
self.value = value;
self.status = 'fulfilled';
self.onFulfilledCallbacks.forEach(item => item(value));
}
}
function reject(reason) {
if (self.status === 'pending') {
self.reason = reason;
self.status = 'rejected';
self.onRejectedCallbacks.forEach(item => item(reason));
}
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
複製程式碼
Instance Method(內建方法)
-
resolvePromise(私有方法)
-
Promise
解析過程 是以一個promise
和一個值做為引數的抽象過程,可表示為[[Resolve]](promise, x)
-
如果
promise
和x
指向相同的值, 使用TypeError
做為原因將promise
拒絕。 -
如果
x
是一個promise
, 採用其狀態:- 如果
x
是pending
狀態,promise
必須保持pending
走到x
fulfilled
或rejected
. - 如果
x
是fulfilled
狀態,將x
的值用於fulfill
promise
. - 如果
x
是rejected
狀態, 將x的原因用於reject promise
.
- 如果
-
如果
x
是一個物件或一個函式:- 將
then
賦為x.then
. - 如果在取
x.then
值時丟擲了異常,則以這個異常做為原因將promise
拒絕。 - 如果
then
是一個函式, 以x
為this
呼叫then
函式, 且第一個引數是resolvePromise
,第二個引數是rejectPromise
,且:- 當
resolvePromise
被以y
為引數呼叫, 執行[[Resolve]](promise, y)
. - 當
rejectPromise
被以r
為引數呼叫, 則以r為原因將promise拒絕。 - 如果
resolvePromise
和rejectPromise
都被呼叫了,或者被呼叫了多次,則只第一次有效,後面的忽略。 - 如果在呼叫
then
時丟擲了異常,則: * 如果resolvePromise
或rejectPromise
已經被呼叫了,則忽略它。 * 否則, 以e
為reason
將promise
拒絕。
- 當
- 如果
then
不是一個函式,則 以x
為值fulfill promise
。
- 將
-
如果
x
不是物件也不是函式,則以x
為值fulfill promise
。
-
//利用Symbol值的唯一性,將私有方法的名字命名為一個Symbol值
const _resolvePromise = Symbol('resolvePromise')
[_resolvePromise](promise2, x, resolve, reject) {
let self = this
if (promise2 === x) {
return reject(new TypeError('迴圈引用'))
}
let then, called
if (x != null && ((typeof x == 'object' || typeof x == 'function'))) {
try {
then = x.then
if (typeof then == 'function') {
then.call(x, function (y) {
if (called)return
called = true
self[_resolvePromise](promise2, y, resolve, reject)
}, function (r) {
if (called)return
called = true
reject(r)
});
} else {
resolve(x)
}
} catch (e) {
if (called)return
called = true
reject(e)
}
} else {
resolve(x)
}
}
複製程式碼
==以下未完待填坑==
-
then
-
catch
Static Method(靜態方法)
-
all
-
race
-
resolve
-
reject
參考資料
- https://segmentfault.com/a/1190000002452115
- http://liubin.org/promises-book/