開發很多的時候需要異步操作,常用的做法就是用回調函數,假如需要一連串的調用,並且后面一個調用依賴前一個返回的結果的時候,就得多層嵌套回調函數,比如下面這種情況:
$('.animateEle').animate({ opacity:'.5' }, 4000,function(){ //回調
$('.animateEle2').animate({ width:'100px' },2000,function(){ //回調
$('.animateEle3').animate({ height:'0' },1000,function(){ .......太亂 }); }); });
回調函數嵌入太多了,看暈了都,代碼很不美觀,於是es6加入了新特性解決這個問題,Promise.
Promise最大的好處就是可以鏈式的調用函數,起到異步回調函數的作用,看起來更加直觀簡潔,
resolve 和 reject
這是Promis最重要的兩個方法,resolve方法可以讓Promise對象的狀態變為成功,reject是失敗,舉個例子一目了然:
function print (ready) { return new Promise ((resolve, reject)=>{ if(ready){ resolve("Hello World!"); }else{ reject("Good bye!"); } }) } print(true).then(message=>{ alert(message); },error=>{ alert(error); } );
then
Promise通常配合then方法來鏈式的使用,then方法里面第一個回調函數表示成功狀態,也就是resolve,第二個是失敗狀態-reject,如果默認寫一個參數的話,默認resolve
代碼會輸出 Hello World!
一個看不出來,多幾個依賴狀態就看着明顯了:
function Print (ready) { return new Promise ((resolve,reject)=>{ if(ready){ resolve("Hello World!"); }else{ reject("Good bye!"); } }); } function print1 () { alert("World"); } function print2 () { alert("!"); } Print(true) .then(message=>{alert(message);}) .then(print1) .then(print2)
上面的代碼依次等到上一個Promise對象返回成功后依次調用,否則按照老式的寫法還得包進回調函數里,包好幾層就很不方便容易看暈,這樣鏈式的調用取代老式寫法,這是Promise最常用的。
catch:
當返回發生錯誤的時候,會觸發catch,可以寫成then(fn).catch(fn),相當於 then(fn).then(null, fn);
function Print (ready) { return new Promise ((resolve,reject)=>{ if(ready){ resolve("Hello World!"); }else{ reject("Good bye!"); } }); } function print1 () { alert("World"); } function print2 () { alert("!"); } function catch_error () { alert('error'); } Print(false) .then(message=>{alert(message);}) .then(print1) .then(print2) .catch(catch_error)
失敗的狀態其實可以寫進then的第二個參數里,但是一般不用那么些,用catch捕獲更符合promise的初衷
all:
Promise.all 可以接收一個元素為 Promise 對象的數組作為參數,當這個數組里面所有的 Promise 對象都變為 resolve 時,該方法才會返回
var p1 = new Promise(resolve=>{ setTimeout(()=>{ resolve("Hello"); },3000); }); var p2 = new Promise(resolve=>{ setTimeout(()=>{ resolve("World"); },1000); }); Promise.all([p1, p2]).then(result=>{ console.log(result); });
還有一個和 Promise.all 相類似的方法 Promise.race,它同樣接收一個數組,不同的是只要該數組中的 Promise 對象的狀態發生變化(無論是 resolve 還是 reject)該方法都會返回。
es6的Promise還有一些方法,就不寫了,以上是常用的.
es7里還有async函數,也起到異步作用,就不多說了先.
兼容性不是很好,vue開發的時候常常會用babel轉碼,要么使用jquery的Deferred對象,用法跟Promise差不多。
