- 每個(gè)promise都有一個(gè)內(nèi)部屬性
[[PromiseState]]
被用來(lái)表示Promise
的三種狀態(tài),初始化的狀態(tài)都是pending
署隘。 - 所有的
promise
都有then()
方法:接受兩個(gè)參數(shù),一個(gè)是當(dāng)promise的狀態(tài)變?yōu)?code>fulfilled時(shí)腹躁,要調(diào)用的函數(shù),第二個(gè)是當(dāng)Promise狀態(tài)變?yōu)?code>rejected時(shí),需要調(diào)用的函數(shù) - 用Promise構(gòu)造函數(shù)可以創(chuàng)建新的Promise,構(gòu)造函數(shù)接受初始化Promise代碼的
executor
坦报,executor
里面有兩個(gè)參數(shù),一個(gè)是`resolve狂鞋,一個(gè)是
reject```片择。
依據(jù)這些內(nèi)容,我們可以搭建出promise的大概架構(gòu):
const PENDING = 'PENDING';
const FULLFILLED = 'FULLFILLED';
const REJECTED = 'REJECTED';
class NewPromise {
constructor(executor) {
// 每個(gè)promise 初始化狀態(tài)是pending
this._currentState = PENDING;
let resolev = () => {};
let reject = () => {};
// 構(gòu)造函數(shù)中立即執(zhí)行構(gòu)造器
executor(resolev, reject);
}
then(onResolved, onRejected) {}
catch (cb) {
return this.then(null, cb)
}
}
promise的狀態(tài)變化
- executor函數(shù)報(bào)錯(cuò) 直接執(zhí)行reject();
- 當(dāng)執(zhí)行期成功時(shí)骚揍,不可轉(zhuǎn)為其他狀態(tài)字管,且必須有一個(gè)不可改變的值(value)
- 當(dāng)執(zhí)行期失敗時(shí),不可轉(zhuǎn)為其他狀態(tài)信不,且必須有一個(gè)不可改變的原因(reason)
constructor(executor) {
// 每個(gè)promise 初始化狀態(tài)是pending
this._currentState = PENDING;
// 成功的值
this.value = undefined;
// 失敗的原因
this.reason = undefined;
let resolve = (value) => {
// 執(zhí)行器調(diào)用resolve后,promise的狀態(tài)變?yōu)槌晒? this._currentState = FULLFILLED;
// 儲(chǔ)存成功的值
this.value = value;
};
let reject = (reason) => {
// 執(zhí)行器調(diào)用reject后,promise的狀態(tài)變?yōu)槭? this._currentState = REJECTED;
// 儲(chǔ)存失敗的原因
this.reason = reason;
};
// 構(gòu)造函數(shù)中立即執(zhí)行構(gòu)造器
try {
executor(resolve, reject);
} catch (err) {
reject(err)
}
}
then方法的實(shí)現(xiàn)
- then方法的兩個(gè)參數(shù)都是可選的
- 當(dāng)狀態(tài)state為fulfilled嘲叔,則執(zhí)行onFulfilled,傳入this.value抽活。當(dāng)狀態(tài)state為rejected硫戈,則執(zhí)行onRejected,傳入this.reason
- onFulfilled,onRejected如果他們是函數(shù)下硕,則必須分別在fulfilled丁逝,rejected后被調(diào)用,value或reason依次作為他們的第一個(gè)參數(shù)
then(onResolved, onRejected) {
// 狀態(tài)為fulfilled卵牍,執(zhí)行onFulfilled果港,傳入成功的值
if (this.state === FULLFILLED) {
onResolved(this.value);
};
// 狀態(tài)為rejected,執(zhí)行onRejected糊昙,傳入失敗的原因
if (this.state === REJECTED) {
onRejected(this.reason);
};
}
- 由于一個(gè)promise可以有多個(gè)then辛掠,所以存在先將then里面的兩個(gè)函數(shù)儲(chǔ)存起來(lái)數(shù)組內(nèi)。
Promise的鏈?zhǔn)秸{(diào)用
我門(mén)常常用到new Promise().then().then()
,這就是鏈?zhǔn)秸{(diào)用,鏈?zhǔn)秸{(diào)用在then方法中返回了一個(gè)新的promise
- 為了達(dá)成鏈?zhǔn)绞臀覀兡J(rèn)在第一個(gè)then里返回一個(gè)promise萝衩。規(guī)定了一種方法,就是在then里面返回一個(gè)新的promise,稱為promise2:
promise2 = new Promise((resolve, reject)=>{})
- 將這個(gè)promise2返回的值傳遞到下一個(gè)then中
- 如果返回一個(gè)普通的值没咙,則將普通的值傳遞給下一個(gè)then中
2猩谊、當(dāng)我們?cè)诘谝粋€(gè)then中return
了一個(gè)參數(shù)(參數(shù)未知,需判斷)祭刚。這個(gè)return出來(lái)的新的promise就是onFulfilled()
或onRejected()
的值牌捷。
then(onFulfilled,onRejected) {
// 聲明返回的promise2
let promise2 = new Promise((resolve, reject)=>{
if (this.state === 'fulfilled') {
let x = onFulfilled(this.value);
// resolvePromise函數(shù)墙牌,處理自己return的promise和默認(rèn)的promise2的關(guān)系
resolvePromise(promise2, x, resolve, reject);
};
if (this.state === 'rejected') {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
};
if (this.state === 'pending') {
this.onResolvedCallbacks.push(()=>{
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
})
this.onRejectedCallbacks.push(()=>{
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
})
}
});
// 返回promise,完成鏈?zhǔn)? return promise2;
}