ES6 Promise對象詳解

promise對象是ES6提供的一個隊列對象,可用於處理回調地獄問題。git

1 Promise的用法

首先先看一個ES5中常見的回調地獄。github

$.ajax({
    url:xx,
    success:function() {
        $.ajax({    //完成第一個請求的時候發起第二個請求
            url:xx.
            success:function() {
                $.ajax({    //完成第二個請求的時候發起第三個請求
                    url:xx.
                    success:function() {
                        $.ajax({
                            //繼續發起下一次請求
                        });
                    }
                });
            }
        });
    }
});
複製代碼

有一系列請求,他們須要前一個請求發送完畢時才能夠發起請求,當嵌套多層請求時,代碼的可讀性和可維護性大大減低。經過Promise能夠有效的解決這個問題。ajax

1.1 概念

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時執行第二個函數。第二個參數能夠不傳入。模塊化

1.2 promise改寫回調地獄

經過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();
        });
    })
})
複製代碼

2 Promise提供的方法

除了then(),Promise還提供了一些經常使用的靜態方法。post

2.1 all()

有時候,咱們但願在執行某個任務以前,必需要先執行其餘的幾個任務,不使用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({    //第一個任務與第二個任務同時完成後,才執行第三個任務
            
    });
});
複製代碼

2.2race()

race也是Promise的靜態方法,用法與all()相似,也是接收一個Promise數組,不一樣點是all()方法是等數組中的全部任務同時執行,且全部任務執行完畢纔將狀態由pedding轉爲fulfilled,race()方法是數組中的全部任務同時執行,有一個任務執行完畢時,就將狀態由pedding轉爲fulfilled。

2.3resolve()

recolve()方法接收一個變量,根據變量的類型有不一樣的表現

  • 接收一個Promise對象,直接將該Promise對象返回。
  • 接收一個帶有then方法的對象,將對象轉換爲Promise對象後執行then方法。
  • 接收的變量不是Promise對象也沒有then方法,返回resolve狀態的Promsie對象。

2.4reject()

reject()方法直接返回一個reject狀態的Promise對象。

更多ES6精髓如模塊化請看ES6快速入門

3交流

若是這篇文章幫到你了,以爲不錯的話來點個Star吧。 github.com/lizijie123

相關文章
相關標籤/搜索