24. Promise是什么?怎么用排嫌?
1. Promise定義
Promise
是一種異步編程的解決方案畸裳。它可以使異步操作更加清晰、簡單淳地、優(yōu)雅怖糊,避免了回調地獄
的問題。Promise
對象表示一個異步操作的最終完成或失敗颇象,并且它的最終狀態(tài)(完成或失斘樯恕)和返回值(或錯誤)不依賴于調用它的代碼。
2. Promise狀態(tài)
Promise
對象有三個狀態(tài):pending
(等待中)遣钳、fulfilled
(已完成)和 rejected
(已拒絕)扰魂。Promise
實例是在創(chuàng)建時就立即執(zhí)行的,并返回一個 Promise 對象。通過使用 then
方法可以注冊成功(fulfilled
)和失斎捌馈(rejected
)狀態(tài)的回調函數(shù)姐直。
3. Promise基本用法:
// 異步獲取數(shù)據(jù)
function getData(name) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(name === "Jack") {
resolve({name: "Jack", age: 20})
} else {
reject("請求錯誤!")
}
}, 2000)
})
}
getData("Jack").then(res => {
console.log(res);//{name: 'Jack', age: 20}
}).catch(err => {
console.log(err);
});
getData("Jarry").then(res => {
console.log(res);
}).catch(err => {
console.log(err);//請求錯誤!
});
4. Promise的實例方法和類方法
1. 實例方法: then()、catch()和finally()蒋畜,Promise的實例方法返回的都是Promise對象简肴,都可以鏈式調用
- then()方法
// then() fulfilled和rejected狀態(tài)都不可修改,即先執(zhí)行的先生效
const p1 = new Promise((resolve, reject) => {
resolve("then res");//fulfilled狀態(tài)
reject("then err");//rejected狀態(tài)
})
p1.then(res => {
console.log(res);//then res
}, err => {
console.log(err);
})
const p2 = new Promise((resolve, reject) => {
reject("then err");//rejected狀態(tài)
resolve("then res");//fulfilled狀態(tài)
})
p2.then(res => {
console.log(res);
}, err => {
console.log(err);//then err
})
// then()方法的鏈式調用 then方法使用上個then方法的返回值作為參數(shù)
const p3 = new Promise((resolve, reject) => {
resolve("then res1")
})
p3.then(res => {
console.log(res);//then res1
return "then res2"
}).then(res => {
console.log(res);//then res2
return "then res3"
}).then(res => {
console.log(res);//then res3
})
- catch()方法
// catch方法是then(null, err => {})的語法糖
const p4 = new Promise((resolve, reject) => {
reject("catch err")
})
p4.then(null, err => {
console.log(err);//catch err
})
p4.catch(err => {
console.log(err);//catch err
})
// catch()方法鏈式調用
p4.catch(err => {
console.log(err);//catch err
throw "catch err1"
}).catch(err => {
console.log(err);//catch err1
throw "catch err2"
}).catch(err => {
console.log(err);//catch err2
})
- finally()方法
// finally()方法 不管什么狀態(tài)最終都會執(zhí)行
const p5 = new Promise((resolve, reject) => {
resolve("fulfilled")
// reject("rejected")
})
p5.then(res => {
console.log(res);//fulfilled
}).catch(err => {
console.log(err);//
}).finally(() => {
console.log("finally msg");//finally msg
})
// finally()鏈式調用 finally的回調函數(shù)沒有參數(shù)
p5.then(res => {
console.log(res);//fulfilled
}).finally(() => {
console.log("finally msg1");//finally msg1
return "finally res"
}).finally((res) => {
console.log(res);//undefined
console.log("finally msg2");//finally msg2
})
2. 類方法(靜態(tài)方法): resolve()百侧、reject()、all()能扒、allSettled()佣渴、race()和any(),可以用來創(chuàng)建 Promise 對象初斑、處理多個 Promise 對象辛润、轉換非 Promise 對象為 Promise 對象等等
- resolve()
// resolve()
// 1. 傳入普通值
const p6 = Promise.resolve("resolve res")
// 相當于
const p7 = new Promise((resolve, reject) => {
resolve("resolve res")
})
p6.then(res => console.log(res));//resolve res
p7.then(res => console.log(res));//resolve res
// 2. 傳入Promise 直接返回這個Promise對象
const p8 = Promise.resolve(p7)
p8.then(res => console.log(res));//resolve res
// 3. 傳入thenable對象 包裝成Promise后返回
const p9 = Promise.resolve({ then: (resolve, reject) => {
resolve("thenable resolve res")
}})
p9.then(res => console.log(res));//thenable resolve res
- reject()
// reject() Promise.reject(reason):創(chuàng)建一個狀態(tài)為已拒絕(rejected)并且拒絕原因為 reason 的 Promise 對象。
// 1. 傳入普通值
const p10 = Promise.reject("reject msg")
p10.catch(err => console.log(err));//reject msg
// 2. 傳入Promise Promise包一層rejected狀態(tài)的Promise返回
const p11 = Promise.reject(new Promise((resolve, reject) => {
resolve("Promise reject msg")
}))
p11.catch(err => {
err.then(res => {
console.log(res);//Promise reject msg
})
})
// 3. 傳入thenable 返回的thenable對象當做錯誤信息輸出
const p12 = Promise.reject({ then: (resolve, reject) => {
reject("thenable reject msg")
}})
p12.catch(err => console.log(err));//{then: ?}
- all()
Promise.all(iterable)
:接收一個可迭代對象(如數(shù)組)见秤,返回一個新的Promise
對象砂竖。如果可迭代對象中的所有Promise
對象都變成已解決狀態(tài),則返回的Promise
對象變成已解決狀態(tài)鹃答,并且其值為一個數(shù)組乎澄,數(shù)組中的元素分別是可迭代對象中每個Promise
對象的解決結果;否則测摔,返回的Promise
對象變成已拒絕狀態(tài)置济,并且其拒絕原因為第一個拒絕的Promise
對象的拒絕原因。
//全部resolve,等最后一個狀態(tài)變成fulfilled時锋八,輸出結果
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise1");
}, 1000)
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise2");
}, 2000)
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise3");
}, 3000)
})
Promise.all([promise1, promise2, promise3]).then(res => {
console.log(res);//['Promise1', 'Promise2', 'Promise3']
}).catch(err => {
console.log(err);
})
//遇到第一個reject就中止并拋出錯誤
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise1");
}, 1000)
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve("Promise2");
reject("Promise2 reject");
}, 2000)
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve("Promise3");
reject("Promise3 reject");
}, 3000)
})
Promise.all([promise1, promise2, promise3]).then(res => {
console.log(res);//['Promise1', 'Promise2', 'Promise3']
}).catch(err => {
console.log(err);//Promise2 reject
})
- allSettled()
// allSettled() 把所有的對應的狀態(tài)和值輸出
Promise.allSettled([promise1, promise2, promise3]).then(res => {
console.log(res);//[{status: 'fulfilled', value: 'Promise1'}, {status: 'rejected', reason: 'Promise2 reject'}, {status: 'rejected', reason: 'Promise3 reject'}]
}).catch(err => {
console.log(err);
})
- race()
//比賽浙于,誰先改變狀態(tài)就返回誰的值
Promise.race([promise1, promise2, promise3]).then(res => {
console.log(res);//Promise1
}).catch(err => {
console.log(err);
})
- any()
// any() 有一個狀態(tài)變?yōu)閒ulfilled則改變狀態(tài)并返回第一個fulfilled狀態(tài)的值,若全部狀態(tài)都為rejected,則返回rejected狀態(tài)
Promise.any([ promise2, promise3]).then(res => {
console.log(res);
}).catch(err => {
console.log(err);//AggregateError: All promises were rejected
})