ES6中promise詳解及用法實(shí)例
一、什么是Promise
Promise是ES6異步編程的一種解決方案(目前最先進(jìn)的解決方案是async和await的搭配(ES8),但是它們是基于promise的),從語法上講,Promise是一個(gè)對(duì)象或者說是構(gòu)造函數(shù),用來封裝異步操作并可以獲取其成功或失敗的結(jié)果。
二、為什么要使用promise
最重要也是最主要的一個(gè)場(chǎng)景就是ajax和axios請(qǐng)求。通俗來說,由于網(wǎng)速的不同,可能你得到返回值的時(shí)間也是不同的,但是我們下一步要執(zhí)行的代碼依賴于上一次請(qǐng)求返回值,這個(gè)時(shí)候我們就需要等待,結(jié)果出來了之后才知道怎么樣繼續(xù)下去。
三、promise的好處
1.可以避免多層異步調(diào)用嵌套問題(回調(diào)地獄)
2.Promise 對(duì)象提供了簡(jiǎn)潔的API,使得控制異步操作更加容易(js執(zhí)行機(jī)制導(dǎo)致的異步問題)
這兩點(diǎn)在我ES6專欄的相關(guān)文章有很詳細(xì)的介紹,這里就不展開了
四、promise的三種狀態(tài)
Promise對(duì)象有三種狀態(tài),他們分別是:
1.pending: 等待中,或者進(jìn)行中,表示還沒有得到結(jié)果
2.resolved(Fulfilled): 已經(jīng)完成,表示得到了我們想要的結(jié)果,可以繼續(xù)往下執(zhí)行
3.rejected: 也表示得到結(jié)果,但是由于結(jié)果并非我們所愿,因此拒絕執(zhí)行
這三種狀態(tài)不受外界影響,而且狀態(tài)只能從pending改變?yōu)閞esolved或者rejected,并且不可逆
五、promise的用法
1.promise的實(shí)例方法
①then()得到異步任務(wù)的正確結(jié)果
②catch()獲取異常信息
③finally()成功與否都會(huì)執(zhí)行(尚且不是正式標(biāo)準(zhǔn))
注意:then方法可以接受兩個(gè)函數(shù),第一個(gè)函數(shù)為promise狀態(tài)為成功的回調(diào)函數(shù),第二個(gè)函數(shù)為promise狀態(tài)為失敗的回調(diào)函數(shù)(可以不寫,一般用catch方法捕獲promise狀態(tài)為失敗的異常信息)
2.promise的對(duì)象方法(p1,p2,p3為promise的實(shí)例對(duì)象)
①Promise.all()并發(fā)處理多個(gè)異步任務(wù),所有任務(wù)都執(zhí)行完成才能得到結(jié)果
Promise.all( [p1,p2,p3] ) .then ( (result) => {consoleog (result)
})②Promise.race()并發(fā)處理多個(gè)異步任務(wù),只要有一個(gè)任務(wù)完成就能得到結(jié)果
Promise.race ( [p1,p2,p3] ).then ( (result)=>{
console. log (result)
})六、promise的特點(diǎn)
1.在Promise對(duì)象的構(gòu)造函數(shù)中,將一個(gè)函數(shù)作為第一個(gè)參數(shù)。
2.而Promise對(duì)象的構(gòu)造函數(shù)的第一個(gè)參數(shù)中的這個(gè)函數(shù),就是用來處理Promise的狀態(tài)變化,這個(gè)函數(shù)的第一個(gè)參數(shù)表示promise的狀態(tài)為成功,第二個(gè)參數(shù)表示promise的狀態(tài)為失敗,這兩個(gè)參數(shù)(名字可以自己命名)都為一個(gè)函數(shù),他們的作用分別是將promise狀態(tài)修改為resolved(成功)和rejected(失敗)。
<script>
function fn(flag) {
//構(gòu)造函數(shù)
return new Promise(function(resolve, reject) {
if (flag === true) {
resolve('promise狀態(tài)為成功!')
};
if (flag === false) {
reject('promise狀態(tài)失?。?)
};
})
}
console.log(fn(true));
</script>控制臺(tái)運(yùn)行:

3. Promise對(duì)象中的then方法,可以接收構(gòu)造函數(shù)中處理的狀態(tài)變化,并分別對(duì)應(yīng)執(zhí)行。then方法有2個(gè)函數(shù)參數(shù),第一個(gè)函數(shù)接收resolved(promise狀態(tài)為成功)的執(zhí)行,第二個(gè)函數(shù)接收reject(promise狀態(tài)為失敗)的執(zhí)行。
<script>
function fn(flag) {
return new Promise(function(resolve, reject) {
if (flag === true) {
resolve('promise狀態(tài)為成功!')
};
if (flag === false) {
reject('promise狀態(tài)失??!')
};
}).then(function(res) {
console.log(res);
},
function(err) {
console.log(err);
})
}
fn(true)
fn(false)
</script>控制臺(tái)運(yùn)行:

4.promise的狀態(tài)只能從 未完成->完成, 未完成->失敗 且狀態(tài)不可逆轉(zhuǎn)。
promise的異步結(jié)果,只能在完成狀態(tài)時(shí)才能返回,而且我們?cè)陂_發(fā)中是根據(jù)結(jié)果來選擇來選擇狀態(tài)的,然后根據(jù)狀態(tài)來選擇是否執(zhí)行then()。
實(shí)例化的Promise內(nèi)部會(huì)立即執(zhí)行,then方法中的異步回調(diào)函數(shù)會(huì)在腳本中所有同步任務(wù)完成時(shí)才會(huì)執(zhí)行。因此,promise的異步回調(diào)結(jié)果最后輸出。示例代碼如下:
var promise = new Promise(function(resolve, reject) {
console.log('Promise instance');
resolve();
});
promise.then(function() {
console.log('resolved result');
});
for(var i=0;i<100;i++) {
console.log(i);
/*
Promise instance
1
2
3
...
99
100
resolved result
*/5.Promise.then()方法
①then()函數(shù)返回的實(shí)際也是一個(gè)Promise對(duì)象(無論函數(shù)內(nèi)部返回什么類型的數(shù)據(jù),函數(shù)都會(huì)進(jìn)行加工返回一個(gè)promise對(duì)象)
<script>
function fn(flag) {
return new Promise(function(resolve, reject) {
if (flag === true) {
resolve('promise狀態(tài)為成功!')
};
if (flag === false) {
reject('promise狀態(tài)失敗!')
};
})
}
console.log(fn(true).then());
</script>控制臺(tái)運(yùn)行:

②then()函數(shù)內(nèi)部返回為普通值(非Promise類型的屬性),返回的普通值會(huì)直接傳遞給下一個(gè)then,通過then參數(shù)中函數(shù)的參數(shù)接收該值。
這時(shí)then()函數(shù)返回的Promise對(duì)象狀態(tài)為成功(resloved),then()函數(shù)的返回值為對(duì)象的成功值,如return 123,返回的Promise對(duì)象值為123,如果沒有返回值,是undefined
<script>
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用戶數(shù)據(jù)');
})
});
let result = p.then(value => {
return 123;
}, reason => {
console.log(reason)
})
console.log(result);
result.then(function(res) {
console.log(res);
})
</script>控制臺(tái)運(yùn)行:

③ 當(dāng)then()函數(shù)內(nèi)部返回的是Promise類型的對(duì)象時(shí),then()函數(shù)的返回的Promise對(duì)象的狀態(tài)值為這個(gè)Promise對(duì)象的狀態(tài)值,成功值也是如此,返回的該promise對(duì)象會(huì)調(diào)用下一個(gè)then方法。
<script>
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用戶數(shù)據(jù)');
})
});
let result = p.then(value => {
return new Promise((resolve, reject) => {
resolve('ok')
})
}, reason => {
console.log(reason)
})
console.log(result);
result.then(function(res) {
console.log(res);
})
</script>控制臺(tái)運(yùn)行:

④當(dāng)then()函數(shù)內(nèi)部果拋出異常,則then()函數(shù)的返回值狀態(tài)也是rejected
<script>
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用戶數(shù)據(jù)');
})
});
let result = p.then(value => {
throw 123
}, reason => {
console.log(reason)
})
console.log(result);
</script>控制臺(tái)運(yùn)行:

6.Promise.catch()方法
①catch()函數(shù)只有一個(gè)回調(diào)函數(shù),意味著如果Promise對(duì)象狀態(tài)為失敗就會(huì)調(diào)用catch()方法并且調(diào)用回調(diào)
//catch()函數(shù)只有一個(gè)回調(diào)函數(shù),意味著如果Promise對(duì)象狀態(tài)為失敗就會(huì)調(diào)用catch()方法并且調(diào)用回調(diào)函數(shù)
<script>
const p = new Promise((resolve, reject) => {
setTimeout(()=>{
reject('出錯(cuò)啦')
},1000)
})
p.catch(reason => {
console.log(reason)
})
</script>控制臺(tái)運(yùn)行:

七、總結(jié)
1.promise其實(shí)就是一個(gè)對(duì)象或者說是構(gòu)造函數(shù)
2.promise的出現(xiàn)(es6) 就是解決異步編程和回調(diào)地獄等問題,async和await的出現(xiàn)(ES8)就是基于promise的一種解決異步編程的終極解決方案(簡(jiǎn)化代碼等等)
3.在前端中,ajax和axios都會(huì)用到異步編程,axios更是基于promise的,所以一定要掌握promise以及用async和await搭配promise的使用
到此這篇關(guān)于ES6中promise詳解及用法的文章就介紹到這了,更多相關(guān)ES6 promise用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript一個(gè)判斷瀏覽器類型的函數(shù)(類)
javascript一個(gè)判斷瀏覽器類型的函數(shù)(類)...2007-08-08
Javascript中匿名函數(shù)的調(diào)用與寫法實(shí)例詳解(多種)
js中定義函數(shù)的方式有很多種,函數(shù)直接量就是其中一種,下面通過本文給大家介紹匿名函數(shù)是如何調(diào)用的及匿名函數(shù)的n中寫法,對(duì)js匿名函數(shù)調(diào)用,js匿名函數(shù)寫法相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-01-01
JavaScript判斷數(shù)組是否包含指定元素的方法
這篇文章主要介紹了JavaScript判斷數(shù)組是否包含指定元素的方法,涉及javascript中contains方法的使用技巧,需要的朋友可以參考下2015-07-07
微信小程序 行的刪除和增加操作實(shí)現(xiàn)詳解
這篇文章主要介紹了微信小程序 行的刪除和增加操作實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
JS數(shù)組reduce你不得不知道的25個(gè)高級(jí)用法
reduce作為ES5新增的常規(guī)數(shù)組方法之一,對(duì)比forEach 、filter和map,在實(shí)際使用上好像有些被忽略,下面這篇文章主要給大家介紹了關(guān)于JS數(shù)組reduce你不得不知道的25個(gè)高級(jí)用法,需要的朋友可以參考下2021-06-06
琥珀無限級(jí)聯(lián)動(dòng)菜單-JavaScript版
琥珀無限級(jí)聯(lián)動(dòng)菜單-JavaScript版...2006-11-11
JavaScript實(shí)現(xiàn)將網(wǎng)頁加入收藏夾功能
瀏覽器出于安全和隱私的考慮,限制了用代碼將網(wǎng)頁加入瀏覽器的收藏夾,本文主要介紹了如何使用通過一些間接的方法實(shí)現(xiàn)這一功能,有需要的可以參考下2024-10-10

