手寫一個Promise的封裝承接上文繼續進行:
上文實作功能:
功能1:搭建Promise基本結構實作
功能2:resolve、reject結構功能實作
鏈接直達:https://blog.csdn.net/czj1049561601/article/details/113829149#comments_15053958
本文實作封裝功能:
功能1:throw拋出例外改變promise狀態功能實作
功能2:確保Promise狀態只能修改一次的功能實作
- throw拋出例外改變Promise物件的狀態
前情介紹:
改變Promise物件狀態的方式有三種:
1:呼叫resolve(' ok ')
2: 呼叫reject(' error')
3: 通過拋出例外來改變,語法上來說,等同與reject 會把物件狀態改變為失敗
明確目的:
正常來說,console的promise物件p 應該是一個失敗的狀態
同上篇博文介紹,利用throw ”error“ 來改變失敗狀態,預期輸出列印物件的情況如下,內置的兩個屬性有相應的狀態

let p=new Promise((resolve,reject)=>{
// resolve('OK');
// reject('error');
// 拋出例外
throw "error" //在promise執行器函式中執行的
})
console.log(p)
- 于是需要在Promise.js中做相應的封裝處理來實作:
思路:
1:一看到throw,就應該想到try...catch 來處理這個拋出的例外
2:于是下一個問題:try..catch 加在代碼的那個位置?
throw ”error " 是在promise執行器函式中執行的,于是promise.js中有如下封裝
邏輯思路展示(重點):
1:實體物件p中拋出例外,期望改變promise狀態為失敗,內部封裝處理時是在執行器函式執行時
2:throw出的erro直接作為引數傳進catch中,然后呼叫reject直接來改變狀態,同上一篇中的resolve/reject 功能實作!
3:鏈接直達:https://blog.csdn.net/czj1049561601/article/details/113829149#comments_15053958

示例代碼如下(resolve/reject代碼片段也放進來,原理見上一篇分析):
// 宣告建構式
function Promise(executor){
// 添加屬性,以便下面修改
this.PromiseState="pendding";
this.PromiseResult=null;
// 保存實體物件的 this 的值
const self=this;
// resolve函式
function resolve(data){
// 1.修改物件的狀態
self.PromiseState="fulfilled";//和resolved一樣的含義,都表示成功
// 2.設定物件的結果值
self.PromiseResult=data;
}
// reject函式
function reject(data){
// 1.修改物件的狀態
self.PromiseState="rejected";
// 2.設定物件的結果值
self.PromiseResult=data;
}
try{
// 同步呼叫 -- 執行器函式
executor(resolve,reject);
}catch(err){
// 修改 promise 物件的狀態為失敗
reject(err);
}
}
// 添加then方法
Promise.prototype.then=function(onResolved,onRejectd){
}
實體結果:

- 驗證對比
可以去掉代碼中的script參考,來使用內部的promise,而非自定義的查看效果,結果相同!
<title>Promise封裝</title>
//<script src="./Promise.js"></script>//注釋掉這里,重新運行進行對比
<script>
let p=new Promise((resolve,reject)=>{
// resolve('OK');
// reject('error');
// 拋出例外
throw "error"
})
console.log(p)
</script>
4. 封裝繼續----確保狀態只能修改一次
邏輯思路
思路很簡單:在改變狀態之前進行相應的判斷即可,在resove / reject 封裝代碼中加入如下判斷確保狀態單次更改
// 判斷狀態
if(self.PromiseState !== 'pendding') return;
// resolve函式
function resolve(data){
// 判斷狀態
if(self.PromiseState !== 'pendding') return;
// 1.修改物件的狀態
self.PromiseState="fulfilled";//和resolved一樣的含義,都表示成功
// 2.設定物件的結果值
self.PromiseResult=data;
}
完整代碼如下:
//------------------------------Promise.js代碼---------------------------
// 宣告建構式
function Promise(executor){
// 添加屬性,以便下面修改
this.PromiseState="pendding";
this.PromiseResult=null;
// 保存實體物件的 this 的值
const self=this;
// resolve函式
function resolve(data){
// 判斷狀態
if(self.PromiseState !== 'pendding') return;
// 1.修改物件的狀態
self.PromiseState="fulfilled";//和resolved一樣的含義,都表示成功
// 2.設定物件的結果值
self.PromiseResult=data;
}
// reject函式
function reject(data){
// 判斷狀態
if(self.PromiseState !== 'pendding') return;
// 1.修改物件的狀態
self.PromiseState="rejected";
// 2.設定物件的結果值
self.PromiseResult=data;
}
try{
// 同步呼叫 -- 執行器函式
executor(resolve,reject);
}catch(err){
// 修改 promise 物件的狀態為失敗
reject(err);
}
}
// 添加then方法
Promise.prototype.then=function(onResolved,onRejectd){
}
}
演示結果:
同時存在resolve(”OK“)以及 reject (” error“)來判斷Promise狀態是否單次執行
let p = new Promise((resolve, reject) => {
resolve('OK');//更換二者位置進行驗證如下,符合預期結果,封裝成功,
reject('error');
// 拋出例外
// throw "error"
})
console.log(p)
運行驗證如下:


上述封裝均符合文章開篇的預期結果,比較簡單,邏輯明白即可!其他功能封裝繼續!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/261857.html
標籤:其他
