--- tags: JS新手特訓班-每日 title: JS新手特訓班 - 第四十關 - this、promis、fetch --- # 第四十關 - ES6 團戰關卡 ## 使用ES6撰寫之前關卡 [第35關](https://codepen.io/hsuan333/pen/OJMdNZe) ## 熱門面試題目 a. 請解釋什麼是 `this`?請寫範例解釋? - [this筆記](https://hackmd.io/SqjqVhCORxqV5LeQ9Q3lHA)(第39關筆記) b. 你對 `promise`、`promise all` 有多熟悉?請寫範例解釋? - [codePen筆記](https://codepen.io/hsuan333/pen/NWxZZwo?editors=1111) c. 什麼是原型繼承(prototype)? d. Fetch 與 XMLHttpRequest - [fetch筆記](https://hackmd.io/omNqXoRiT5aBQDG2SC_YFA)(無XMLHttpRequest)(第36關筆記) --- ### Promise #### Promise是甚麼? **Promise 是 ES6所新增的建構函式**,像 Date()也是建構函式, 最常見的例子就是 axios或 fetch使用 Promise的方式解決 AJAX的非同步問題,同時也增強可讀性( callback巢到不行~),像是這樣: ```javascript= const apiUrl = '遠端資料網址' // axios 版本 axios .get(apiUrl) .then((res) => { console.log(res) }) // fetch 版本 fetch(apiUrl) .then(response => { return response.json(); }) .then(jsonData => { apiData = jsonData; updateData(apiData); }) ``` #### 為什麼需要 Promise? 它又用來做甚麼? JavaScript是單執行緒,也就是說一次只能做一件事,按照程式碼來看就是由上往下依序執行,然而碰到某些特殊事件,就會先擺著,也就是 Event queue (事件佇列),像是: - AJAX行為 - 監聽事件(click、change、...) - `setTimeout( () => { } )` 下面的例子會怎樣出現? ```javascript= console.log('小杰') setTimeout( () => { console.log('英雄 - 一拳超人') }, 0) console.log('小杰師傅') // 可以丟到 codePen看看 // 會發現 setTimeout秒數就算設定為0,也會是最後出現 ``` 為了解決 Event queue所帶來的非同步問題,也就是事情被先擺著不做,最後才做,可以使用 Promise語法來避免拖延症 #### Promise如何建立? 一開始 Promise會先待機,根據使用者認為該情況正確就使用 resoleve()回傳資料,不正確則是用 reject()回傳失敗訊息 - Promise是建構函式,所以需要先使用 new這個語法轉換成物件型式 - resolve與 reject可自定義參數名稱,不過為了避免混淆,還是習慣使用預設名稱 - 原本函式需要使用 return來回傳函式執行完畢後要的資料,在 Promise則是使用不同的方式回傳(不只有 resolve()、reject() ) ```javascript= const get = (data) =>{ return new Promise((resolve, reject) => { if (data) { // 若正確完成,使用 resolve()回傳 resolve('要回傳的資料') } else { // 失敗後,使用 reject()回傳 reject('要回傳的失敗訊息') } }) } ``` #### Promise如何接收回傳? 回想一下 axios是如何從遠端資料接收資料的呢? - 使用 then()來接收 resolve()的資料 - 使用 catch()來接收 reject()的資料 ```javascript= // 接續 Promise如何建立? 的程式碼 let example = 1; get(apiUrl) .then((res) => { console.log(res) }) .catch((res) => { console.log(res) }) // 範例中因為有資料傳入,所以會回傳 '要回傳的資料' // 若 example改為 0,則會回傳 '要回傳的失敗訊息',0與1會自動轉型 false與 true ``` #### 如果有很多個 Promise型式的函式需要執行該怎麼做? 假設有多個遠端資料需要等待它們撈取回來再處理資料,像是這樣: ```javascript= // 接續 Promise如何接收回傳? 的程式碼 // apiUrl1與 apiUrl2為範例字串,get()無 xhr功能 const apiUrl1 = "https//:遠端資料網址/直播班成員.json" const apiUrl2 = "https//:遠端資料網址/特訓班成員.json" // Promise語法是大寫 Promise.all([get(apiUrl), get(apiUrl2)]) .then(res => { console.log(res) }) ``` - **Promise.all**,等待全部執行完畢才回傳資料,陣列的順序與傳入的函式一致 - 除了 Promise.all還有其他方式 - Promise.race,傳回第一個跑完的 - Promise.resolve,直接定義 resolve,但無法取得失敗訊息 - Promise.reject,直接定義 reject,,但無法取得成功資料或訊息 #### 參考 - [JavaScript Promise 全介紹](https://wcc723.github.io/development/2020/02/16/all-new-promise/) - [IT邦 Promise(1)](https://ithelp.ithome.com.tw/articles/10197427) - [一次只能做一件事情的 JavaScript](https://wcc723.github.io/javascript/2017/12/07/javascript-event-queue/) ### 原型繼承prototype