前端開發由於網絡交互的存在,產生了一種最多見的獨特場景——異步,即程序執行的過程並不是徹底按照代碼的書寫順序執行。異步編程的解決方法有①回調函數、②事件、③Promise、④觀察者對象;
Promise是ES6提供的一種異步編程的一種解決方案。簡單來書就是一個容器,裏面存放着某個將來纔會結束的事件;從語法角度來講是一個構造函數(對象),能夠對各類異步操做進行一樣的處理方法。前端
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建立時當即執行 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返回值可帶參數 var p1=new Promise(function(resolve,reject){}); var p2=new Promise(function(resolve,reject){ // do some other things... resolve(p1); }) // 案例3 :Promise狀態定型的會回調函數在本輪事件循環結束時執行 new Promise((resolve,reject)=>{ console.log(1); resolve(2); console.log(3); }).then(res=>{ console.log(res); }) // 1 // 3 // 2 // 案例4:顯示return語句後的代碼不執行 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構造函數接受一個函數做爲參數,參數函數提供兩個參數方法,分別是resolve和reject,這兩個方法有JavaScript引擎提供,不用本身部署;Promise實例建立後會當即執行,而後會執行代碼中全部的同步操做, 最後會在Promise狀態定型後,執行then方法指定的回調函數 ;Promise的回調函數resolve和reject均可帶有參數;Promise的回調函數在狀態定性後的下一輪事件中執行,即不管狀態在何處定型(resolve()),都不影響Promise中其餘代碼的執行,但顯示
return
語句會影響;編程
Promise.prototype.then(resolveFn,rejectFn?)
:爲Promise實例添加狀態改變是的回調函數,返回至爲Promise對象;該方法可鏈式重複調用,將前一個處理結果做爲下一個函數的入參,如:promise.then().then()
Promise.prototype.catch()
:指定Promise發生錯誤時的回調函數,返回值爲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的狀態一旦定性將沒法被改變,即一個Promise實例有且僅有一次改變狀態的機會 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接口的數據對象包裝成一個新的Promise實例,返回值;①參數arrLike能夠是Promise數組、或具備遍歷器的數據;若是參數不是Promise數組,則調用Promise.resolve()方法將參數轉爲Promise實例,在進一步處理;數組
②返回Promise實例的狀態:被封裝的Promise實例都爲Fullfiled狀態時,封裝返回Promise狀態纔會變成Fullfied;不然只要有一個爲rejected,則會將第一個rejected的實例返回給封裝後的Promise,同時,封裝後的Promise都會變成rejected;promise
let pro1=new Promise.all([p1,p2,p3]); let pro2=new Promise.all([1,2,3]);
Promise.race(arrLike)
:將多個具備Iterator接口的數據包裝成一個Promise實例;與Promise.all()方法相似;不一樣之處在於,只要被包裝的Promise實例只要有一個率先改變狀態,變回將狀態結果傳遞給封裝後的Promise對象;Promise.resolve(argu)
:將一個數據轉換成Promise對象;根據傳入參數類型的不一樣處理方法不一樣,以下:thenable
對象:即一個具備then
方法的對象;將這個對象轉換成Promise對象並當即執行htneable的then方法;Promise.reject(argu)
:返回一個Promise對象,其狀態爲Rejected;錯誤結果爲整個參數自己;