class封裝完整版
(function(window){
// 進行中狀態
const _PENDING = "pending";
// 已成功狀態
const _RESOLVED = "resolved";
// 已失敗狀態
const _REJECTED = "rejected";
class MyPromise {
constructor(executor) {
// 設置狀態初始值爲 pending
this.status = _PENDING;
// 設置初始值爲 undefined
this.value = undefined;
// 添加回調函數隊列
this.onCallBacks = [];
// 成功時執行
function _resolve(value) {
if (this.status !== "pending")
return;
// 修改 MyPromise 對象的狀態爲 resolve
this.status = _RESOLVED;
// 保存成功的數據
this.value = value;
//檢查回調數組中是否存在數據
if (this.onCallBacks.length > 0) {
// 異步執行
setTimeout(() => {
this.onCallBacks.forEach(onCb => {
onCb.onResolved.call(this);
});
});
}
}
// 失敗時執行
function _reject(reason) {
if (this.status !== "pending")
return;
// 修改 MyPromise 對象的狀態爲 resolve
this.status = _REJECTED;
// 保存失敗的數據
this.value = reason;
//檢查回調數組中是否存在數據
if (this.onCallBacks.length > 0) {
// 異步執行
setTimeout(() => {
this.onCallBacks.forEach(onCb => {
onCb.onRejected.call(this);
});
});
}
}
try {
// 立即執行 executor
executor(_resolve.bind(this), _reject.bind(this))
} catch (err) {
_reject.call(this, err);
}
}
then(onResolved, onRejected) {
return new MyPromise((resolve, reject) => {
/*
* 參數 cb 的值爲 onResolved 或 onRejected 函數
* */
function _callback(cb) {
// 增加try方法,如果出現異常,執行reject
try {
let result = cb(this.value);
// 判斷返回結果是否爲MyPromise類型
if (result instanceof MyPromise) {
// result 是 MyPromise,下面這行代碼是上方代碼的簡寫形式
result.then(resolve, reject);
} else {
// 非MyPromise類型,將結果直接傳遞過去
resolve(result);
}
} catch (err) {
// 出現異常,執行reject
reject(err);
}
}
// 防止使用者不傳成功或失敗回調函數,所以成功失敗回調都給了默認回調函數
onResolved = typeof onResolved === "function" ? onResolved : value => value;
onRejected = typeof onRejected === "function" ? onRejected : error => {
throw error
};
switch (this.status) {
// 當狀態爲resolve時,執行onResolved,並傳遞結果
case _RESOLVED:
// 通過 setTimeout 讓代碼異步執行
setTimeout(() => {
_callback.call(this, onResolved);
});
break;
// 當狀態爲reject時,執行onRejected,並傳遞結果
case _REJECTED:
// 通過 setTimeout 讓代碼異步執行
setTimeout(() => {
_callback.call(this, onRejected);
});
break;
// 當狀態爲 pending 時,將要執行的回調函數放置到隊列中,待狀態更改完畢後再調用。
case _PENDING:
this.onCallBacks.push({
onResolved() {
//獲取回調函數的執行結果
_callback.call(this, onResolved);
},
onRejected() {
_callback.call(this, onRejected);
}
});
break;
}
})
}
catch = function (onRejected) {
return this.then(undefined, onRejected);
}
// 函數對象 resolve 的封裝
static resolve(value) {
return new MyPromise((resolve, reject) => {
if (value instanceof MyPromise) {
value.then(resolve, reject);
} else {
resolve(value);
}
});
}
// 函數對象 reject 的封裝
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
})
}
//函數對象 all 的封裝
static all(MyPromises) {
return new MyPromise((resolve, reject) => {
let pValues = [];
let flag = 0;
for (let i = 0; i < MyPromises.length; i++) {
MyPromises[i].then(v => {
pValues[i] = v;
flag++;
if (flag >= MyPromises.length) {
resolve(pValues);
}
}, r => {
reject(r);
})
}
});
}
//函數對象 race
static race(MyPromises) {
return new MyPromise((resolve, reject) => {
for (let i = 0; i < MyPromises.length; i++) {
MyPromises[i].then(value => {
resolve(value);
}, reason => {
reject(reason);
})
}
});
}
}
window.MyPromise = MyPromise;
})(window)
—————END—————
喜歡本文的朋友們,歡迎關注公衆號 張培躍,收看更多精彩內容!!