手寫 promise 之路
先看一下我們正常的使用場(chǎng)景
var test = new TestPromise((res,rej)=> {
setTimeout(() => {
res(99999)
},1000)
})
test.then((a) => {
console.log(1111,a)
})
這是按照使用場(chǎng)景的第一次嘗試的代碼
class TestPromise {
constructor(callback) {
this.status = 'pending'
callback(this.resolve, this.reject)
}
resolve = (data) => {
if(this.status == 'pending') {
this.status = 'resolve'
console.log('進(jìn)入resolve')
return data
}
}
reject = (data) => {
if(this.status == 'pending') {
this.status = 'reject'
console.log('進(jìn)入reject')
return data
}
}
then = (resolveResult) => {
console.log(this.status)
if(this.status == 'resolve') {
resolveResult()
}
}
}
運(yùn)行一下看一下打印結(jié)果
pending
進(jìn)入resolve
此時(shí)發(fā)現(xiàn)會(huì)先執(zhí)行我們的 then 方法,然后在執(zhí)行的 resolve 方法這和我們預(yù)期的完全不一樣, 因?yàn)榘凑疹A(yù)期應(yīng)該是等 resolve 后在執(zhí)行 then 方法,這個(gè)時(shí)候才想到是缺了發(fā)布訂閱的通知,所以下面的步驟應(yīng)該是能有一個(gè)發(fā)布訂閱的消息通知。網(wǎng)上關(guān)于發(fā)布訂閱這一塊已經(jīng)說的很多了,這里就不綴余了。代碼如下:
/**
* 事件監(jiān)聽
*/
let keyCount = 1;
export default class Monitor {
list: any = {};
// 注冊(cè)
on = (fun: any = () => {}) => {
const key = `key-${keyCount++}-${+new Date()}`;
this.list[key] = fun;
return {
key,
off: () => {
this.off(key);
}
};
};
// 注冊(cè)一次執(zhí)行后關(guān)閉
once = (fn: any = () => {}) => {
const _id = this.on((res: any) => {
_id.off();
return fn(res);
});
return _id;
};
// // 刪除
off = (key: string | number) => {
delete this.list[key];
return true;
};
go = (...res: any) => {
const resList = [];
for (const key in this.list) {
try {
resList.push(this.list[key](...res));
} catch (e) {
resList.push(new Error(e));
}
}
return resList;
};
// // 刪除所有事件注冊(cè)
offAll = () => {
this.list = {};
return true;
};
}
加上兩個(gè)數(shù)組用來存儲(chǔ)事件(傳統(tǒng)的是用對(duì)象來當(dāng)事件中心,但是我們不需要定義事件的名稱,所以就直接用兩個(gè)數(shù)組來儲(chǔ)存就行了,因?yàn)槲覀兊氖录椭挥袃蓚€(gè))
class TestPromise {
constructor(callback) {
this.status = "pending";
this.resolveEventArr = [];
this.rejectEventArr = [];
callback(this.resolve, this.reject);
}
resolve = (data) => {
if (this.status == "pending") {
this.status = "resolve";
this.resolveEventArr.forEach((item) => item(data));
console.log("進(jìn)入resolve");
}
};
reject = (data) => {
if (this.status == "pending") {
this.status = "reject";
this.rejectEventArr.forEach((item) => item(data));
console.log("進(jìn)入reject");
}
};
then = (resolveEvent, rejectEvent) => {
console.log(this.status);
if (this.status == "pending") {
this.resolveEventArr.push(resolveEvent);
this.rejectEventArr.push(rejectEvent);
}
};
}
var test = new TestPromise((res, rej) => {
setTimeout(() => {
res(99999);
}, 1000);
});
test.then((a) => {
console.log(1111, a);
});
最后編輯于 :2020.12.17 13:59:47
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者 【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。 平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。