JS_觀念_Promise

Promise是ES_6的語法,針對JS做非同步的處理。
非同步就是不用等上一部執行完成,才做下一步,每個步驟是可以同步執行的。
一個Promise建構式在被創造時,必須傳入一個函式作為參數,這函式會帶有兩個參數-resolve成功 or reject失敗,其中只能回傳這兩結果其中之一也只能回傳一次,回傳後便結束Promise事件。

語法

  • Promise本身是個建構函式,函式也是物件的一種,所以可以添加屬性,像是all/ race/ resolve/ reject,並且有then/ catch/ finally這些方法。
    這些方法必須在產生新物件下才能呼叫。

const creatPromise = new Promise((resolve, reject)=>{
    /**成功時回傳的**/
    resolve(status)
    
    /**失敗時回傳的**/
    reject(status)
    
}).then((data)=>{
    /**用 then 接續成功時的處理**/
    
}).catch((error)=>{
    /**用 catch 接續失敗時的處理**/
    
    }).finally(() =>{
    /**用 finally 表結束的處理**/
    console.log("finish")
    })

then 的串聯

當一個then結束後,除了可以接catch表達失敗的結果,原本的then本身也可以在接另外一個then。
這時第二個then的callback function裡的參數,其實是第一個then所丟出來的回傳值,在收到值後產生新的promise物件,在呼叫建構式裡的resolve參數,把收到的值傳入。

利用promise改寫XMLHttpRequest

  • XMLHttpRequest 是歷史擁久的WebAPI,主要可以操作HTTP請求,進行網路作業,擷取資料時,不需進行頁面reload。

  • 以往的寫法

        var url = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
        var req = new XMLHttpRequest();
        req.open('GET', url);
        req.onload = function () {
            if (req.status == 200) {
                console.log(req.responseURL)
            }
        }
        req.send()
  • 以Promise寫法:
    之後要在使用只要直接呼叫function get(url),即可執行測試。
        function get(url) {
            return new Promise((resolve, reject) => {
                var req = new XMLHttpRequest();
                req.open('GET', url);
                req.onload = function () {
                    if (req.status == 200) {
                        resolve(JSON.parse(req.response))
                    } else {
                        reject(Error(req))
                    };
                }
                req.send();
            })
        };
        get('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json')
        .then((res) => {
            console.log(res)
        }).catch((res) => {
            console.error(res)
        })

Async/ Await

在ES7 推出了Async/ Await為讓非同步更加便利使用。

Async

Async這個詞字面意思就是非同步,使用它所宣告的函式就是非同步函式,並且以Promise來達成。

用法

用關鍵字Async function 宣告一個函式,並且加上await的運算式,等待Promise解析。例子

        function trustGod(thinking) {
            return new Promise(function (resolve, reject) {

                var faith = "信者得永生";
                var reason = "我還是得新冠了"

                if (thinking) {
                    resolve(faith)
                } else {
                    reject(reason);
                }
            })

        }

        async function test() {
            console.log('執行test1:');

            let test = await trustGod(true)
            console.log('結果是:' + test)
        -----------我是分隔線-----------------------
            console.log('執行test2:');
            test = await trustGod(false)
            console.log("結果是:" + test)

        }
        ------------------------------------------
        console.log('start!!!');
        test();
        console.log('finish!!')

結果是

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

會先出現finish!!,是因爲遇到await trustGod,會先把原本得同步執行玩,在繼續等待解析回傳的resolved 值,若遇到解析失敗rejected,則被拋出外面,並附加原因(如圖中紅色警語般)。

Await 新功能

可以執行非Promise的內容!
await可以直接將100轉換成 Promise.resolve(),並等待解析他

    async function showNum(){
    var x = await 100;
    console.log(x) //100
    }
    showNum();
tags: javascript,觀念