我寫這篇文章不打算介紹Promise產生的緣由以及它解決的問題,我只是想寫一篇關於實現本身Promise的文章。若是代碼以及邏輯有什麼不對的地方,請你們指出來。就這些,開始正題。數組
前提:咱們要知道Promise是基於Promises/A+規範的。其中好多變量和方法名都是從這裏來的。 咱們先從Promise的使用開始,寫幾個測試例子。promise
let promise = new Promise((resolve, reject) =>{
// console.log("1");
// resolve("成功");
// reject("失敗");
// console.log("2");// 第一步
// reject("失敗");
// resolve("成功");// 第二步
// setTimeout(() => {
// resolve("success");
// }, 2000);
throw new Error("手動拋出錯誤");// 第四步
});
promise.then((value) => {
console.log("then第一個方法:"+value);
}, (err) => {
console.log("then第二個方法:"+err);
})
promise.then((value) => {
console.log("then第一個方法:"+value);
}, (err) => {
console.log("then第二個方法:"+err);
})
console.log("3");
複製代碼
第一步輸出緩存
第二步輸出bash
第三步輸出異步
第四步輸出函數
最後輸出「成功」說明 then是異步執行的測試
根據以上幾個例子咱們能夠推出如下幾點內容:ui
這麼一大坨東西,看着有點亂。咱們就根據咱們得出的結論開始寫屬於本身的Promise。寫的過程當中思路慢慢就清晰了。this
let myPromise = function (executor) {
let self = this;//緩存一下this
self.status = 'pending';// 狀態管理 狀態的變化只能由pending變爲resolved或者rejected。一件事情不能既成功又失敗。因此resolved和rejected不能相互轉化。
self.value = undefined;// 成功後的值 傳給resolve
self.reason = undefined;//失敗緣由 傳給reject
self.onResolvedCallbacks = [];// 存放then中成功的回調
self.onRejectedCallbacks = []; // 存放then中失敗的回調
// 這裏說明一下,第三步使用定時器。執行完 new Promise 以後,會執行then方法,此時會把then中的方法緩存起來,並不執行:此時狀態仍是pending。等到定時器2秒以後,執行
// resolve|reject 時,而是依次執行存放在數組中的方法。 參考發佈訂閱模式
function resolve(value) {
// pending => resolved
if (self.status === 'pending') {
self.value = value;
self.status = 'resolved';
// 依次執行緩存的成功的回調
self.onResolvedCallbacks.forEach(fn => fn(self.value));
}
}
function reject(reason) {
// pending => rejected
if (self.status === 'pending') {
self.value = value;
self.status = 'rejected';
// 依次執行緩存的失敗的回調
self.onRejectedCallbacks.forEach(fn => fn(self.reason));
}
}
try {
//new Promise 時 executor執行
executor(resolve, reject);
} catch (error) {
reject(error);// 當executor中執行有異常時,直接執行reject
}
}
// 每一個Promise實例上都有then方法
Promise.prototype.then = function (onFulfilled, onRejected) {
let self = this;
// 執行了 resolve
if (self.status === 'resolved') {
// 執行成功的回調
onFulfilled(self.value);
}
// 執行了 reject
if (self.status === 'rejected') {
// 執行失敗的回調
onRejected(self.reason);
}
// new Promise中能夠支持異步行爲 當既不執行resolve又不執行reject時 狀態是默認的等待態pending
if (self.status === 'pending') {
// 緩存成功的回調
self.onResolvedCallbacks.push(onFulfilled);
// 緩存失敗的回調
self.onRejectedCallbacks.push(onRejected);
}
};
複製代碼
說明一下:這是最簡版,由於Promise的強大之處是鏈式調用。咱們這個只是雛形,因爲時間關係。咱們先到這裏。下一次咱們基於這個雛形實現符合Promises/A+規範的完整版。spa
第一次發表文章,但願各位大蝦多多支持。