什么是Promise?前端开发人员会使用Promise简直就是如虎添翼
生活随笔
收集整理的這篇文章主要介紹了
什么是Promise?前端开发人员会使用Promise简直就是如虎添翼
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、什么是Promise
目錄
一、什么是Promise
1.Promise到底是做什么的呢?
2.什么是回調(diào)地獄。
二、Promise基本語法
三、什么情況下需要使用Promise
四、Promise三種狀態(tài)
五、Promise鏈?zhǔn)秸{(diào)用
六、Promise的all方法調(diào)用(某一個(gè)需求需要發(fā)送兩次請(qǐng)求)
一、什么是Promise
1.Promise到底是做什么的呢?
Promise是異步編程的種解決方案 那什么時(shí)候我們會(huì)來處理異步事件呢? 一種很常見的場(chǎng)景應(yīng)該就是網(wǎng)絡(luò)請(qǐng)求了。 我們封裝一個(gè)網(wǎng)絡(luò)請(qǐng)求的函數(shù),因?yàn)椴荒芰⒓茨玫浇Y(jié)果,所以不能像簡(jiǎn)單的3+4=7—樣將結(jié)果返回。 所以往往我們會(huì)傳入另外—個(gè)函數(shù),在數(shù)據(jù)請(qǐng)求成功時(shí),將數(shù)據(jù)通過傳入的函數(shù)回調(diào)出去。 如果只是一個(gè)簡(jiǎn)單的網(wǎng)絡(luò)請(qǐng)求,那么這種方案不會(huì)給我們帶來很大的麻煩 但是,當(dāng)網(wǎng)絡(luò)請(qǐng)求非常復(fù)雜時(shí),就會(huì)出現(xiàn)回調(diào)地獄。2.什么是回調(diào)地獄。
我們來考慮下面的場(chǎng)景(有夸張的成分): 我們需要通過一個(gè)urI從服務(wù)器加載一個(gè)數(shù)據(jù)data,data1中包含了下一個(gè)請(qǐng)求的url2 我們需要通過data1取出url2,從服務(wù)器加載數(shù)據(jù)data2,data2中包含了下ー個(gè)請(qǐng)求的url3 我們需要通過data2取出urI3,從服務(wù)器加載數(shù)據(jù)data3,data3中包含了下ー個(gè)請(qǐng)求的ur4 發(fā)送網(wǎng)絡(luò)請(qǐng)求ur4,獲取最終的數(shù)據(jù)data4 上面的代有什么問題嗎? 正常情況下,不會(huì)有什么問題,可以正常運(yùn)行并目獲取我們想要的結(jié)果 但是,這樣的代看而且不容易維護(hù) 我們更加期望的是一種更加優(yōu)雅的方式來進(jìn)行這種異步操作。 如何做呢?就是使用 Promise。——Promise可以以一種非常優(yōu)雅的方式來解決這個(gè)問題。二、Promise基本語法
1.這里,我們用個(gè)定時(shí)器來模擬異步事件: 假設(shè)下面的data是從網(wǎng)絡(luò)上1秒后請(qǐng)求的數(shù)據(jù) console. log就是我們的處理方式。 這是我們過去的處理方式,我們將它換成 Promise代碼 這個(gè)例子會(huì)讓我們感覺脫褲放屁,多此一挙 首先,下面的 Promise代碼明顯比上面的代碼看起來還要復(fù)雜 其次,下面的 Promise代嗎中包含的 resolve、 reject、then、catch都是些什么東西? 我們先不管第一個(gè)復(fù)雜度的問題,因?yàn)檫@樣的一個(gè)屁大點(diǎn)的程序根本看不出來 Promise真正的作用. 2.上代碼 <script>// new Promise時(shí)有兩個(gè)參數(shù),resolve, reject,這兩個(gè)參數(shù)同時(shí)又是函數(shù)new Promise((resolve, reject) => {// 1.第一次網(wǎng)絡(luò)請(qǐng)求setTimeout(function() {// 一秒后會(huì)執(zhí)行console.log('time out')resolve('Hello world') // 調(diào)用resolve之后,會(huì)調(diào)用下面的then//失敗時(shí)調(diào)用reject// reject('Error data')}, 1000)}).then(data => {// 2.第一次拿到結(jié)果console.log(data)return new Promise((resolve, reject) => {// 3.第二次網(wǎng)絡(luò)請(qǐng)求setTimeout(function() {// 一秒后會(huì)執(zhí)行console.log('time out2')resolve('Hello world2') // 調(diào)用resolve之后,會(huì)調(diào)用下面的thenreject('Error data2')}, 1000)}).then(data => {// 4.第二次拿到結(jié)果處理console.log(data)}).catch(error => {console.log(error)})//如果還有處理,可以繼續(xù)return new Promise}).catch(error => {console.log(error)})// new Promise是異步處理,不影響后面的邏輯console.log('最后的') </script> 3.另外一種寫法 <script>// new Promise時(shí)有兩個(gè)參數(shù),resolve, reject,這兩個(gè)參數(shù)同時(shí)又是函數(shù)new Promise((resolve, reject) => {// 1.第一次網(wǎng)絡(luò)請(qǐng)求setTimeout(function() {// 一秒后會(huì)執(zhí)行console.log('time out')resolve('Hello world') // 調(diào)用resolve之后,會(huì)調(diào)用下面的thenreject('Error data')}, 1000)}).then(data => {// 2.第一次拿到結(jié)果// 只寫一個(gè)then,可以傳入兩個(gè)函數(shù),一個(gè)resolve執(zhí)行,一個(gè)reject執(zhí)行console.log(data)}, error => {console.log(error)})</script>三、什么情況下需要使用Promise
在進(jìn)行異步請(qǐng)求時(shí),使用Promise對(duì)這個(gè)異步操作進(jìn)行封裝。 在處理完結(jié)果之后,使用resolve方法就會(huì)調(diào)用promise后面的then方法;報(bào)錯(cuò)之后,reject會(huì)調(diào)用catch方法。 在執(zhí)行傳入的回調(diào)函數(shù)時(shí),會(huì)傳入兩個(gè)參數(shù),resolve、reject,本身又是函數(shù)四、Promise三種狀態(tài)
首先,當(dāng)我們開發(fā)中有異步操作時(shí),就可以給異步操作包裝一個(gè)Promise。異步操作之后會(huì)有三種狀態(tài): pending:等待狀態(tài),比如正在進(jìn)行網(wǎng)絡(luò)請(qǐng)求,或者定時(shí)器沒有到時(shí)間。 fulfill:滿足狀態(tài),當(dāng)我們主動(dòng)回調(diào)了resolve時(shí),就處于該狀態(tài),并且會(huì)回調(diào)then() reject:拒絕狀態(tài),當(dāng)我們主動(dòng)回調(diào)了reject時(shí),就處于該狀態(tài),并且會(huì)回調(diào)catch() ?五、Promise鏈?zhǔn)秸{(diào)用
1.鏈?zhǔn)秸{(diào)用new Promise((resolve, reject) => {setTimeout(() => {resolve('aaa')}, 1000)}).then(res => {//1.自己處理10行代碼console.log(res, '第一層的10行處理代碼')// 2.對(duì)結(jié)果進(jìn)行第一次處理,可以只用resolvereturn new Promise((resolve) => {resolve(res + '111')})}).then(res => {console.log(res, '第二層的10行處理代碼')return new Promise((resolve) => {resolve(res + '222')})}).then(res => {console.log(res, '第三層的10行處理代碼')})//???aaa 第一層的10行處理代碼 //???aaa111 第二層的10行處理代碼 //???aaa111222 第三層的10行處理代碼2.簡(jiǎn)化鏈?zhǔn)絥ew Promise((resolve, reject) => {setTimeout(() => {resolve('aaa')}, 1000)}).then(res => {//1.自己處理10行代碼console.log(res, '第一層的10行處理代碼')// 2.對(duì)結(jié)果進(jìn)行第一次處理,可以只用resolvereturn Promise.resolve(res + '111')}).then(res => {console.log(res, '第二層的10行處理代碼')return Promise.resolve(res + '222')}).then(res => {console.log(res, '第三層的10行處理代碼')})//???aaa 第一層的10行處理代碼 //???aaa111 第二層的10行處理代碼 //???aaa111222 第三層的10行處理代碼3.極度簡(jiǎn)化new Promise((resolve, reject) => {setTimeout(() => {resolve('aaa')}, 1000)}).then(res => {//1.自己處理10行代碼console.log(res, '第一層的10行處理代碼')// 2.對(duì)結(jié)果進(jìn)行第一次處理,可以只用resolvereturn res + '111'}).then(res => {console.log(res, '第二層的10行處理代碼')return res + '222'}).then(res => {console.log(res, '第三層的10行處理代碼')})//???aaa 第一層的10行處理代碼 //???aaa111 第二層的10行處理代碼 //???aaa111222 第三層的10行處理代碼4.reject的簡(jiǎn)寫new Promise((resolve, reject) => {setTimeout(() => {resolve('aaa')}, 1000)}).then(res => {//1.自己處理10行代碼console.log(res, '第一層的10行處理代碼')// 2.對(duì)結(jié)果進(jìn)行第一次處理,可以只用resolvereturn Promise.reject(res + '111')//throw 'errormsg' //?手動(dòng)拋出異常也可以}).then(res => {console.log(res, '第二層的10行處理代碼')return Promise.resolve(res + '222')}).then(res => {console.log(res, '第三層的10行處理代碼')}).catch(err => {console.log(err, 'err')})//aaa 第一層的10行處理代碼//aaa111 err六、Promise的all方法調(diào)用(某一個(gè)需求需要發(fā)送兩次請(qǐng)求)
?????Promise.all([new Promise((resolve, reject) => {// 1.第一次請(qǐng)求setTimeout(() => {resolve('aaa1')}, 1000)}),new Promise((resolve, reject) => {// 2.第二次請(qǐng)求setTimeout(() => {resolve('aaa2')}, 2000)})]).then(results => {// 每個(gè)數(shù)組對(duì)應(yīng)每個(gè)Promise,只有所有的Promise都執(zhí)行完畢之后,才會(huì)調(diào)用then方法console.log(results[0])console.log(results[1])})總結(jié)
以上是生活随笔為你收集整理的什么是Promise?前端开发人员会使用Promise简直就是如虎添翼的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis高级-内存淘汰策略
- 下一篇: Vuex-全局状态集中式管理神器,做vu