前端開發(fā)因為網(wǎng)絡交互的存在,產(chǎn)生了一種最常見的獨特場景——異步,即程序執(zhí)行的過程并非完全按照代碼的書寫順序執(zhí)行。異步編程的解決方法有①回調(diào)函數(shù)、②事件、③Promise、④觀察者對象;
Promise是ES6提供的一種異步編程的一種解決方案。簡單來書就是一個容器,里面存放著某個未來才會結束的事件;從語法角度來說是一個構造函數(shù)(對象),可以對各種異步操作進行同樣的處理方法。
1.Promise特點
- 3種狀態(tài):Pending(進行中)、Fulfilled(已成功)、Rejected(已失敗);
- 對象狀態(tài)不受外界影響:只有異步操作的結果可以決定當前是哪一種狀態(tài),任何其他操作都無法改變這個狀態(tài);
- 2種不可逆狀態(tài)改變:只有兩種狀態(tài)改變①Pending->Fulffiled、②Pending->Rejected;只要兩種情況發(fā)生任何一種,狀態(tài)就凝固定型不再改變,即Resolved,任何時候都能且僅能得到這個結果;即使在添加新的對象也立即得到Resolved的結果;
2. 創(chuàng)建方法
- 創(chuàng)建:
let p=new Promise(function(resolved,reject){})
;
var promise=new Promise(function(resolve,rejecte){
//do somthing here
if(/*異步操作成功*/){resolve(value)
}else{reject(value)};
})
// 案例1 :Promise創(chuàng)建時立即執(zhí)行
let promise1=new Promise(function(resolve,reject){
console.log("Promise is creating...");
resolve();
});
promise1.then(function(){console.log("Promise is resolved !")});
console.log("Hi Script is Running...");
// Promise is creating...
// Hi Script is Running...
// Promise is resolved !
// 案例2:Promise返回值可帶參數(shù)
var p1=new Promise(function(resolve,reject){});
var p2=new Promise(function(resolve,reject){
// do some other things...
resolve(p1);
})
// 案例3 :Promise狀態(tài)定型的會回調(diào)函數(shù)在本輪事件循環(huán)結束時執(zhí)行
new Promise((resolve,reject)=>{
console.log(1);
resolve(2);
console.log(3);
}).then(res=>{
console.log(res);
})
// 1
// 3
// 2
// 案例4:顯示return語句后的代碼不執(zhí)行
new Promise(function(resolve,reject){
console.log(1);
return resolve(2);
console.log(3);
}).then(res=>{
console.log(res)
});
console.log(4)
// 1
// 4
// 2
Promise構造函數(shù)接受一個函數(shù)作為參數(shù),參數(shù)函數(shù)提供兩個參數(shù)方法,分別是resolve和reject,這兩個方法有JavaScript引擎提供,不用自己部署;Promise實例創(chuàng)建后會立即執(zhí)行,然后會執(zhí)行代碼中所有的同步操作, 最后會在Promise狀態(tài)定型后,執(zhí)行then方法指定的回調(diào)函數(shù) ;Promise的回調(diào)函數(shù)resolve和reject都可帶有參數(shù);Promise的回調(diào)函數(shù)在狀態(tài)定性后的下一輪事件中執(zhí)行,即無論狀態(tài)在何處定型(resolve()),都不影響Promise中其他代碼的執(zhí)行,但顯示
return
語句會影響;
3. 基本方法
-
Promise.prototype.then(resolveFn,rejectFn?)
:為Promise實例添加狀態(tài)改變是的回調(diào)函數(shù),返回至為Promise對象;該方法可鏈式重復調(diào)用,將前一個處理結果作為下一個函數(shù)的入?yún)?,?promise.then().then()
-
Promise.prototype.catch()
:指定Promise發(fā)生錯誤時的回調(diào)函數(shù),返回值為Promise對象,即Promise.then(null,rejection)
的別名;Promise的錯誤對象具有“冒泡”性質,會一直向后傳遞,直到被catch或reject捕獲;但如果Promise沒有使用catch指定錯誤的處理方法,Promise的錯誤方法將永遠不會傳遞到外層代碼,即不會有任何反應;
// 案例5:Promise 錯誤對象冒泡--then過程中的錯誤會一直傳遞給最后至被捕獲
let p1=new Promise((resolve,reject)=>{resolve(httpFn)});
let p2=new Promise((resolve,reject)=>{p1});
let p3=new Promise((resolve,reject)=>{});
p3.then(p2).then(otherFn).catch(err=>{errorFn});
// 案例6:Promise的狀態(tài)一旦定性將無法被改變,即一個Promise實例有且僅有一次改變狀態(tài)的機會
let p4=new Promise((resolve,reject)=>{
resolve('ok');
throw new Error('test');
});
p4.then(res=>{console.log(res)}).catch(err=>{console.log(err)});
// ok
// 案例7
let soneFn=function(){
return new Promise(function(resolve,reject){
resolve(x+2);//此處應該報錯,因為x未聲名
})
}
someFn.then(function(){console.log('Everythings is ok.')});
// Everything is ok.
/////因未使用catch捕獲Promise異常,報錯不會被捕獲,也不會傳遞到外層代碼;相反代碼正常運行,但會打印錯誤ReferenceError: x is not defined.
-
Promise.all(arrLike)
:將一個具有Iterator接口的數(shù)據(jù)對象包裝成一個新的Promise實例,返回值;
①參數(shù)arrLike可以是Promise數(shù)組、或具有遍歷器的數(shù)據(jù);如果參數(shù)不是Promise數(shù)組,則調(diào)用Promise.resolve()方法將參數(shù)轉為Promise實例,在進一步處理;文章來源:http://www.zghlxwxcb.cn/news/detail-711187.html
②返回Promise實例的狀態(tài):被封裝的Promise實例都為Fullfiled狀態(tài)時,封裝返回Promise狀態(tài)才會變成Fullfied;否則只要有一個為rejected,則會將第一個rejected的實例返回給封裝后的Promise,同時,封裝后的Promise都會變成rejected;文章來源地址http://www.zghlxwxcb.cn/news/detail-711187.html
let pro1=new Promise.all([p1,p2,p3]);
let pro2=new Promise.all([1,2,3]);
-
Promise.race(arrLike)
:將多個具有Iterator接口的數(shù)據(jù)包裝成一個Promise實例;與Promise.all()方法類似;不同之處在于,只要被包裝的Promise實例只要有一個率先改變狀態(tài),變回將狀態(tài)結果傳遞給封裝后的Promise對象; -
Promise.resolve(argu)
:將一個數(shù)據(jù)轉換成Promise對象;根據(jù)傳入?yún)?shù)類型的不同處理方法不同,如下:
① 參數(shù)不存在:直接返回一個狀態(tài)為Resolved的Promise對象;
② Promise對象:返回Promise對象,不做任何處理;
③thenable
對象:即一個具有then
方法的對象;將這個對象轉換成Promise對象并立即執(zhí)行htneable的then方法;
④ 不具有thenable方法或非對象:返回一個新的Promise對象,狀態(tài)為resolved,結果為參數(shù)本身; -
Promise.reject(argu)
:返回一個Promise對象,其狀態(tài)為Rejected;錯誤結果為整個參數(shù)本身;
5. 與steam事件、Observerble(觀察者模式的區(qū)別)
- Promise、Observe都是將異步操作轉換成同步操作的實現(xiàn)方式;
- Promise、Observe都可以進行聚合操作;
- Promise的狀態(tài)是不可逆 的,其狀態(tài)僅有一次改變的機會,一旦改變,狀態(tài)便定型;結果值需要手動調(diào)用才可傳遞給后續(xù)操作
- Observe的狀態(tài)是可以多次重復可變的,其狀態(tài)會根據(jù)入?yún)⒏淖儾鬟f給觀察者;結果值會主動通知到所有訂閱者(后續(xù)操作);
到了這里,關于ES6-10:Promise的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!