什麼是Promise呢?
首先我們先看一個例子
<script>
// 1.封裝異步函數 5.給這個封裝函數傳入三個形參
function getFood(count,successCallback,errCallback){
// 3.聲明一個定時器 來模擬異步操作
setTimeout(()=>{
// 6.判斷這個標識符 成功執行這個函數
if(count>0){
let name = "張三";
let num = 0;
for(let i = 0;i<100;i++){
num++;
}
successCallback(num);
}else{
// 失敗執行這個
errCallback("無了");
}
},3000);
};
// 2.調用這個函數 4.給這個函數傳入三個實參 一個是標識符 一個成功函數 一個失敗函數
getFood(-1,(value)=>{
console.log("這是一個成功的函數",value);
},(err)=>{
console.log("這是一個失敗的函數",err);
});
// 在ES5之前我們都是這樣解決異步處理問題 邏輯沒有問題 也能實現這個操作
// 但是每個人封裝的函數都是不一樣的 有的人喜歡把成功的實參函數寫在前面、中間或者後面
// 實參位置與相對應 形參位置不一致 可能形參成功函數位置對應實參失敗的位置 所以造成了很多麻煩
// 而我們要學的promise就是一個標準 來解決這樣問題
</script>
在上面的解決方案中,我們確確實實可以解決請求函數得到結果之後,獲取到對應的回調,但是它存在兩個主要的問題:
第一,我們需要自己來設計回調函數、回調函數的名稱、回調函數的使用等;
第二,對於不同的人、不同的框架設計出來的方案是不同的,那麼我們必須耐心去看別人的源碼或者文檔,以便可以理解它 這個函數到底怎麼用;
在ES5之前我們都是這樣解決異步處理問題 邏輯沒有問題 也能實現這個操作
但是每個人封裝的函數都是不一樣的 有的人喜歡把成功的實參函數寫在前面、中間或者後面
實參位置與相對應 形參位置不一致 可能形參成功函數位置對應實參失敗的位置 所以造成了很多麻煩
而我們要學的promise就是這樣一個標準
Promise
我們來看一下Promise的API是怎麼樣的:
Promise是一個類,可以翻譯成 承諾、許諾 、期約;
當我們需要的時候,給予調用者一個承諾:待會兒我會給你回調數據時,就可以創建一個Promise的對象;
在通過new創建Promise對象時,我們需要傳入一個回調函數,我們稱之為executor
這個回調函數會被立即執行,並且給傳入另外兩個回調函數resolve、reject;
當我們調用resolve回調函數時,會執行Promise對象的then方法傳入的回調函數;
當我們調用reject回調函數時,會執行Promise對象的catch方法傳入的回調函數;
Promise的代碼結構
上面Promise使用過程,我們可以將它劃分成三個狀態:
待定(pending): 初始狀態,既沒有被兑現,也沒有被拒絕;當執行executor中的代碼時,處於該狀態;
已兑現(fulfilled): 意味着操作成功完成; 執行了resolve時,處於該狀態,Promise已經被兑現;
已拒絕(rejected): 意味着操作失敗;執行了reject時,處於該狀態,Promise已經被拒絕
<script>
// 封裝一個異步請求任務
// 1.封裝函數 4.寫入形參
function getFood(){
// 5. 實例promise對象 這個對象裏面是立即執行函數 兩個參數 resolve reject
const promise = new Promise((resolve,reject)=>{
let name = "張三"; // 待定狀態
let age = 17; // 待定狀態
console.log("我是待定狀態"); // 待定狀態
if(age >= 18){
// 已兑現 狀態
resolve("我是一個成年人");
}else{
// 已拒絕 狀態
reject("我是一個小朋友");
};
});
promise.then((value)=>{
console.log("你今年多大了?",value);
});
promise.catch((err)=>{
console.log("你今年多大了?",err);
})
};
// 2.調用這個函數 3.給這個函數傳入實參
getFood();
</script>