介紹ES7出現的 Async、Await。包含 Promise 概念及新的 fetch 語法糖。

Reference

參考資料

概念

最初的 XMLHttpRequest

不嗦囉,直接看 code

                // 宣告 XHR 的物件
                var Req = new XMLHttpRequest();
                
                Req.open('post', '/blog/GetLearnIndex', true);
                Req.send();
                Req.onload = xmlHttpReqOnload;
                Req.onerror = xmlHttpReqOnError;

                function xmlHttpReqOnload() {
                    const data = JSON.parse(this.responseText);
                    console.log('XMLHttpRequset result : ', data);
                }

                function xmlHttpReqOnError(err) {
                    console.log('錯誤', err)
                }
            

jQuery 的 .ajax ()

請直接參考此範例

Promise

Promise 物件代表一個非同步操作,它有完成、失敗的兩個事件,這兩事件都可以回傳一個值 (物件) 。 回傳的 Promise 必須接 .then(func(){ }); 來 (或是用 await) 處理事情 。

非同步是沒有順序的 (與外部其他同步的程式來比較) , 所以不應與其他程式擺在一起比較先後,而是將它視為獨立執行, 不依賴或相關其他程式的執行。

                let runPromise = (someone, timer, success = true) => {

                    console.log('01.', `${someone} 開始跑開始`);

                    //resolve , reject 是固定要的兩個事件 , 可以使用別的名稱
                    return new Promise((resolve, reject) => {

                        if (success) {

                            setTimeout(function () {

                                // 3 秒時間後,透過 resolve 來表示完成
                                let str = `${someone} 跑 ${timer / 1000} 秒時間(fulfilled)`;
                                console.log('03. ', str)

                                resolve(str);       //成功回傳訊息

                            }, timer);

                        } else {

                            let str = `${someone} 跌倒失敗(rejected)`;
                            console.log('02. ', str);

                            // reject 訊息
                            reject(str)
                        }
                    });
                }

                // 此段函式並不會影響其它函示的執行
                runPromise('小明', 1000, false).then((someone) => {

                    console.log('04. then:', someone)

                }).catch((err) => {

                    console.log('04. error:', err);
                });

                // 以下這段 console 會在 promise 結束前就執行
                console.log('02. | 03. ', '這裡執行了一段 console , 但可能因為 Promise 的速度很快, 所以排在 03');
            

Fetch

Fetch 就是包裝好的 Promise , 可以使用這個來方便地取代 jQuery 的 .ajax

                // Fetch 的基本範例及概念
                fetch(api_url, {})
                    .then((response) => {   // 第一個 then 處理 response 資料內容

                        // response.body    是一個 ReadableStream 的物件
                        // response.ok      true|false
                        // response.status  200 (如果ok的話)
                        console.log('Fetch response : ', response);

                        //處理成自己要用的 資料型態
                        return response.json();

                        //還有下列的方法可將 ReadableString 物件轉換成自己想要處理的物件 , 一般都是 josn
                        //  .arrayBuffer()
                        //  .blob()             //圖片之類的
                        //  .formData()
                        //  .json()
                        //  .text()

                    }).then((data) => { // 第二個 then 處理資料

                        console.log(data);

                    }).catch((err) => {

                        console.log('錯誤:', err);

                    });

                // fetch post 的指定資料
                fetch(api_url, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'      // headers 加入 json 格式
                    },
                    body: JSON.stringify({                      // body 將 json 轉字串送出
                        email: 'lovef1232e@hexschool.com',
                        password: '12345678'
                    })
                }).then((response) => {
                    // 
                }).then((jsonData) => {
                    //
                }).catch((err) => {
                    //
                })
            

async、await

只要有 await 的 function 就一定是 async function..


                let myexe = async function () {

                    const readyData = await LoadData();

                    return readyData;   // 這邊會等 LoadData 完成後回傳
                };

                let LoadData = async () => {

                    let res = await fetch(api_url);

                    let data = await res.json();

                    return data;
                };


                let promise = myexe();              //promise 是一個 Promise 非同步物件

                var res = promise.then((res) => {         //

                    return res;

                }).catch((err) => {

                    console.log('catch exception:', err);

                });

                console.log('finall:', res);