1. 程式人生 > >ES6新增特性——Promise

ES6新增特性——Promise

new 通過 方式 鏈式操作 復雜 程序 行動 變化 settime

一:為什麽會出現?

1、場景一:在很多業務需求中,你需要通過ajax進行多次請求,而且每次請求返回的數據需要作為參數進行下一次的請求,於是會出現ajax層層嵌套問題。多個請求操作層層依賴,加上每一層還會有復雜的業務邏輯需要處理,使得代碼可讀性很差,不直觀,難以維護和調試。

註:這種回調函數層層嵌套又稱為回調地獄

//請求A
    $.ajax({
       success:function (res1) {
           //請求B
           $.ajax({
              success:function (res2) {
                 
//請求C $.ajax({ success:function (res3) { ...... ....... } }) } }) } })

2、場景二:如果請求C依賴於請求A和B的結果,但A和B之間互不依賴,如果仍寫成A嵌套B,B嵌套C的形式,無疑是會消耗更多的等待時間。

故出現Promise對象來更合理和規範地處理異步操作。JS中所有代碼都是單線程執行,如果必須是異步執行,可以通過回調函數實現

二:如何使用?

Promise對象是全局對象,可以理解為一個類。

Promise對象有三種狀態:

pending:剛創建實例,表示初始化狀態
fulfilled:resolve方法調用的時候,表示操作成功

rejected:reject方法調用的時候,表示操作失敗

1、通過new生成一個實例,參數是一個匿名函數,其中有兩個參數resolve,reject

   var pro = new Promise(function (resolve, reject) {
//pending狀態
if (‘操作成功‘) { resolve();//resolve:處理異步操作執行成功後的回調函數 fulfiied狀態 } else { reject();//reject:處理異步操作失敗後的回調函數 rejected狀態 } })

2、then()方法:用於處理操作後的處理程序

   pro.then(function (res) {
        //執行resolve回調函數
    }, function (error) {
        //執行reject回調函數
    })

3、catch()方法:處理操作異常的程序

  pro.catch(function (error) {
        //執行reject回調函數
    })

綜合上面兩個方法,一般用then方法處理操作成功的程序,catch用來處理操作異常的程序

  pro.then(function (res) {
        //執行resolve回調函數
    }).catch(function (error) {
        //執行reject回調函數
    })

完整示例:最後輸出結果為:執行成功

   var pro = new Promise(function (resolve, reject) {
        //pending狀態
        if (true) {
            resolve(‘執行成功‘);//resolve:處理異步操作執行成功後的回調函數  fulfiied狀態
        } else {
            reject(‘執行失敗‘);//reject:處理異步操作失敗後的回調函數  rejected狀態
        }
    })
    pro.then(function (res) {
        //執行resolve回調函數
        console.log(res)
    }).catch(function (error) {
        //執行reject回調函數
        console.log(error)
    })

三:如何解決回調地獄問題?

    var pro = new Promise(function (resolve, reject) {
        if (true) {
            resolve(‘執行成功‘);
        } else {
            reject(‘執行失敗‘);
        }
    })
    pro.then(A)
       .then(B)
       .then(C)
       .catch(D)

    function A(res) {
        console.log(res) //執行成功
        return ‘給下一個B請求傳參:成功執行A‘;
    }
    function B(res) {
        console.log(res) //給下一個B請求傳參:成功執行A
        return ‘給下一個C請求傳參:成功執行B‘;
    }
    function C(res) {
        console.log(res) //給下一個C請求傳參:成功執行B
    }
    function D(error) {
        console.log(error)
    }

可以通過多個then方法進行鏈式操作,通過return方式給下一個執行回調函數傳參,如上示例的結果是

執行成功
給下一個B請求傳參:成功執行A
給下一個C請求傳參:成功執行B

四:如何解決場景二問題?

Promise.all()方法:當參數中的實例對象的狀態都為fulfilled時,Promise.all()才會執行resolve函數

    var pro1 = new Promise(function (resolve, reject) {
       setTimeout(resolve(‘成功執行1‘),5000);
    });
    var pro2 = new Promise(function (resolve, reject) {
        setTimeout(resolve(‘成功執行2‘),1000);
    });
     Promise.all([pro1,pro2]).then(function (res) {
         console.log(res)
     })

pro1在1000ms以後成功進入fulfilled狀態,但此時Promise.all還是不會有行動,需要等到pro2進入到fulfilled狀態時,才會進入then方法,故5000ms以後執行結果為:

[

‘成功執行1‘,
‘成功執行2‘

]

類似的方法還有Promise.race()方法,參數為Promise實例,只要有一個狀態發生改變,不管是成功fulfiied還是失敗rejected狀態,就會有返回,其他實例再有變化也不會再處理了。

   var pro1 = new Promise(function (resolve, reject) {
       setTimeout(resolve,5000,‘成功執行1‘);
    });
    var pro2 = new Promise(function (resolve, reject) {
        setTimeout(reject,1000,‘失敗執行2‘);
    });
     Promise.race([pro1,pro2]).then(function (res) {
         console.log(res)
     }).catch(function (error) {
         console.log(error)
     })

執行結果為:

失敗執行2

ES6新增特性——Promise