promise對象是ES6提供的一個隊列對象,可用於處理回調地獄問題。git
首先先看一個ES5中常見的回調地獄。github
$.ajax({
url:xx,
success:function() {
$.ajax({ //完成第一個請求的時候發起第二個請求
url:xx.
success:function() {
$.ajax({ //完成第二個請求的時候發起第三個請求
url:xx.
success:function() {
$.ajax({
//繼續發起下一次請求
});
}
});
}
});
}
});
複製代碼
有一系列請求,他們須要前一個請求發送完畢時才能夠發起請求,當嵌套多層請求時,代碼的可讀性和可維護性大大減低。經過Promise能夠有效的解決這個問題。ajax
promise是一個先進先出的隊列,向這個隊列中依次添加多個任務(每一個ajax請求能夠視爲一個任務),執行完畢的任務會被推出隊列,而後執行下一個任務。數組
promise存在三個狀態,分別是pending(任務等待或進行中)、fulfilled(任務成功完成,準備執行下一個任務)、rejected(任務完成但失敗了,不執行下一個任務)。狀態只能由pedding轉爲fulfilled/rejected,且不可逆。promise
Promise對象接收一個函數做爲一個任務推動隊列中,函數有resolve和reject兩個參數,調用resolve()表示將狀態由pedding轉爲fulfilled,調用reject()表示將狀態由pedding轉爲rejected。下面看一個列子。bash
new Promise(function(resolve,reject) {
setTimeout(function() {
var ran=Math.random();
if(ran<0.5) {
resolve(ran);
}
else {
reject(ran);
}
},1000);
})
.then(function(ran) {
console.log(ran+'大於0.5');
},function(ran) {
console.log(ran+'小於0.5');
});
複製代碼
在上面的例子中,先定義了一個Promise對象,設置了一個定時器,在1秒以後隨機一個0-1的數,數值小於0.5時,調用resolve()方法將狀態由pedding轉爲fulfilled,數值大於0.5則調用reject()方法,將狀態由pedding轉爲rejected。dom
一旦狀態由pedding轉爲fulfilled或rejected時,Promise對象將當前任務推出隊列,同時執行下一個任務,下一個任務經過Promise對象的then方法傳入,then方法接收兩個函數,上一個任務的狀態爲fulfilled時執行第一個函數,上一個任務的狀態爲rejected時執行第二個函數。第二個參數能夠不傳入。模塊化
經過then方法能夠將回調地獄改寫爲:函數
new Promise(function(resolve,reject){
$.ajax({ //第一個請求
url:xx,
success:function({
resolve();
});
})
})
.then({ //完成第一個請求的時候發起第二個請求
$.ajax({
url:xx,
success:function({
resolve();
});
})
})
.then({ //完成第二個請求的時候發起第三個請求
$.ajax({
url:xx,
success:function({
resolve();
});
})
})
複製代碼
除了then(),Promise還提供了一些經常使用的靜態方法。post
有時候,咱們但願在執行某個任務以前,必需要先執行其餘的幾個任務,不使用promise的時候,咱們會使用一個參數做爲進度條,下面是例子
//不使用Promise
var prog=0; //定義進度條,prog滿100時,執行第三個任務
$.ajax({ //第一個任務
url:xx
success:function() {
prog+=50; //進度條增長50
next(); //查看prog是否滿100,滿了則執行第三個任務
}
});
$.ajax({ //第二個任務
url:xx
success:function() {
prog+=50; //進度條增長50
next(); //查看prog是否滿100,滿了則執行第三個任務
}
});
function next() {
if(prog==100) {
$.ajax({ //第一個任務與第二個任務同時完成後,才執行第三個任務
});
}
}
複製代碼
Promise提供了一個靜態方法all,該方法接收一個Promise數組,數組內的全部任務同時執行,只有全部任務執行完畢時,纔將狀態由pedding轉爲fulfilled。
//使用Promise
let promiseArr=[];
let promise1=new Promise(function(resolve,reject) {
$.ajax({ //第一個任務
url:xx
success:function() {
}
});
});
promiseArr.push(promise1);
let promise2=new Promise(function(resolve,reject) {
$.ajax({ //第二個任務
url:xx
success:function() {
}
});
});
promiseArr.push(promise2);
Promise.all(promiseArr)
.then(function() {
$.ajax({ //第一個任務與第二個任務同時完成後,才執行第三個任務
});
});
複製代碼
race也是Promise的靜態方法,用法與all()相似,也是接收一個Promise數組,不一樣點是all()方法是等數組中的全部任務同時執行,且全部任務執行完畢纔將狀態由pedding轉爲fulfilled,race()方法是數組中的全部任務同時執行,有一個任務執行完畢時,就將狀態由pedding轉爲fulfilled。
recolve()方法接收一個變量,根據變量的類型有不一樣的表現
reject()方法直接返回一個reject狀態的Promise對象。
更多ES6精髓如模塊化請看ES6快速入門。
若是這篇文章幫到你了,以爲不錯的話來點個Star吧。 github.com/lizijie123