天天看點

Promise的各種常用【使用】場景

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <div>es6</div>
        <script type="text/javascript">
            // what是Promise:Promise是ES6中提供的一個異步程式設計的解決方案,Promise本身是一個構造函數 typeof Promise  //  function
            // Promise對象代表一個異步操作,有三種狀态:pending(進行中)、fulfilled(已成功)和rejected(已失敗)
            // 異步操作成功,Promise對象傳回一個值,狀态變為resolved
            // 異步操作失敗,Promise對象抛出一個錯誤,狀态變為rejected
            /*
            一旦Promise狀态改變,就不會再有變化,任何時候都可以得到這個結果。Promise對象的狀态改變,隻有兩種可能:從pending變為fulfilled 或者 從pending變為rejected。
            隻要這兩種情況發生,狀态就不會再變了,會一直保持這個結果,這時就稱為 resolved(已定型)。
            如果改變已經發生了,你再對Promise對象添加回調函數,也會立即得到這個結果。這與事件(Event)不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的;
            Promise優點:
              在處理異步程式時,将異步操作隊列化,按照期望的順序執行,傳回符合預期的結果,這樣即使是多重異步操作,也可以友善的使用Promise進行鍊式調用
            Promise缺點:
              1、無法取消Promise,一旦建立它就會立即執行,無法中途取消。
              2、如果不設定回調函數,Promise内部抛出的錯誤,不會反應到外部。
              3、當處于pending狀态時,無法得知目前進展到哪一個階段(剛剛開始還是即将完成)
            */
            // 基本使用
            const promise = new Promise(function(resolve, reject) {
                console.log('Promise++++++++111111');
                // 執行一個異步操作
                setTimeout(() => {
                    console.log('Promise+setTimeout:最後輸出')
                }, 3000)
                resolve('成功'); // 狀态由等待變為成功,傳的參數作為then函數中成功函數的實參
                // reject('失敗');  // 狀态由等待變為失敗,傳的參數作為then函數中失敗函數的實參
                console.log('Promise++++++++222222');
            })
            // then中有2個參數,第一個參數是狀态變為成功後應該執行的回調函數,第二個參數是狀态變為失敗後應該執行的回調函數。
            promise.then(res => {
                console.log('Promise++++++++444444');
                console.log('結果1:' + res) // 結果1:成功(如果是reject('失敗')則列印結果是:失敗)
            }, err => {
                console.log('錯誤1:' + err)
            }).then(res => {
                console.log('結果2:' + res) // 結果2:undefined
            }, err => {
                console.log('錯誤2:' + err)
            }).finally(() => {
                console.log('結束') // finally方法,finally方法用于指定不管 Promise 對象最後狀态如何,都會執行的操作
            })
            console.log('333333');
            /*總結:上述依次列印 
                Promise++++++++111111
                Promise++++++++222222
                333333
                Promise++++++++444444
                結果1:成功
                結果2:undefined
                結束
                Promise+setTimeout:最後輸出
            */
            /*==========================Promise.all()方法=================================*/
            // 多個 Promise
            const p1 = new Promise((resolve, reject) => {
                setTimeout(function() {
                    console.log('p1')
                    resolve('p1')
                }, 3000)
            })
            const p2 = new Promise((resolve, reject) => {
                setTimeout(function() {
                    console.log('p2')
                    resolve('p2')
                }, 5000)
            })
            // 多個異步操作
            Promise.all([p1, p2]).then((res) => {
                console.log('成功:' + res) // 成功:p1,p2
            })
            /*==========================Promise.race()方法=================================*/
            // race的用法, 文法和all()一樣,但是傳回值有所不同,race根據傳入的多個Promise執行個體,隻要有一個執行個體resolve或者reject,就隻傳回該結果,其他執行個體不再執行,
            // 也就是說多個異步程式,隻傳回響應最快的那個異步程式,不論成功或者失敗,就把最快響應的傳回值傳回,後面的異步程式不再執行
            const p4 = new Promise((resolve, reject) => {
                setTimeout(function() {
                    console.log('p4')
                    resolve('p4')
                }, 9000)
            })

            const p5 = new Promise((resolve, reject) => {
                setTimeout(function() {
                    console.log('p5')
                    reject('p5')
                }, 6000)
            })

            Promise.race([p4, p5]).then().catch(res => {
                console.log('失敗:' + res) // p5 失敗:p5 p4
            })
            /*==========================Promise.resolve()方法=================================*/
            // Promise的resolve方法,用于将非Promise類型的對象,轉為Promise對象,這樣就可以調用Promise原型對象上的方法了
            // 沒有參數,如果沒有參數,這直接傳回一個resolved狀态的Promise對象 
            const p7 = Promise.resolve()
            // 相當于 
            const p8 = new Promise(resolve => {
                resolve(undefined)
            })
            p7.then(res => {
                console.log('p7-resolve()沒有參數時候等價與:' + res) // 輸出 undefined
            })
            // 參數是一個不具有then方法的對象,或者是一個基數資料類型的值,則Promise.resolve方法傳回一個新的 Promise 對象,狀态為resolved,值為指定值
            const p9 = Promise.resolve('123')
            p9.then(res => {
                console.log('p9-resolve()有參數時候等價與:' + res) // 輸出 '123'
            })
            // 參數是一個具有then方法的對象,Promise.resolve方法會将這個對象轉為 Promise 對象,然後就立即執行thenable對象的then方法
            const obj = {
                then: function(resolve, reject) {
                    resolve(100)
                }
            }
            const p10 = Promise.resolve(obj)
            p10.then(res => {
                console.log(res) // 100
            })
            // 特别的:參數是一個Promise對象,那麼将原封不動的傳回這個Promise對象

            // reject與resolve方法基本類似,但是要注意一種情況,就是當參數是一個thenable對象時
            const thenable = {
                then(resolve, reject) {
                    reject('出錯了');
                }
            };
            Promise.reject(thenable)
                .catch(e => {
                    console.log(e === thenable) // true
                })
        </script>
    </body>
</html>