XMLHttpRequest Syntax:
以下 code 改自
Using XMLHttpRequest
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", () => {
// do something
});
oReq.open("GET", URL, true);
oReq.setRequestHeader('Client-ID', clientIdHeader)
oReq.send();
主要指令:
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", () => {})
request.onerror =
- (
oReq.setRequestHeader('Client-ID', clientIdHeader)
) request.send();
原本的 XMLHttpRequest:
修改成 fetch 形式:// set variables const apiUrl = 'https://api.twitch.tv/kraken/' const acceptHeader = 'application/vnd.twitchtv.v5+json' const clientIdHeader = 'bmrryhsxxxxxxxxxxxxxxxxxxxxxxo' // start const requestNavBar = new XMLHttpRequest() requestStreams.addEventListener('load', () => { if (requestStreams.status >= 200 && requestStreams.status < 400) { const jsonStreams = getJsonForm(requestStreams) updateLiveStreams(jsonStreams, streamsNumber) } else { console.log(requestStreams.status, requestStreams.responseText) } }) requestStreams.onerror = () => { console.log('error') } requestStreams.open('GET', `${apiUrl}streams?stream_type=live&game=${topFiveGames[0]}`, true) requestStreams.setRequestHeader('Accept', acceptHeader) requestStreams.setRequestHeader('Client-ID', clientIdHeader) requestStreams.send()
const apiUrl = 'https://api.twitch.tv/kraken/' const acceptHeader = 'application/vnd.twitchtv.v5+json' const clientIdHeader = 'bmrryhsxxxxxxxxxxxxxxxxxxxxxxo' url = `${apiUrl}streams?stream_type=live&game=${topFiveGames[0]}` fetch(url, { method: 'GET', body: JSON.stringify(data), headers: { 'Client-ID': clientIdHeader, 'Accept': acceptHeader }, })
作業名稱
week 13 hw3 twitch API 改寫
碰到的問題一
How to get data returned from fetch() promise?
碰到問題
在 dev tool 查看 network 上的 API 有 GET 到,但是 console 欄沒有印出值。
enter main
result: undefined
預期的行為
印出 data。
enter main
result {_total: 2426, top: Array(5)}
嘗試過的解決方法
擷取自How to get data returned from fetch() promise?
如果在 fetch
最後面加上 .then(data => {console.log(data))
就可以印出 API 資料,但是在 getData() 之外執行 getData()
,就取不到資料,會顯示 undefined。
相關程式碼
const sleep = ms => new Promise(resolve => {
setTimeout(resolve, ms)
})
function getData() {
api200 = 'https://run.mocky.io/v3/0801540d-ad87-4a2f-a5c4-abfb25463ccb';
fetch(api200)
.then((response) => {
return response.json()
})
}
async function main() {
console.log('enter main')
await sleep(1000)
const result = await getData() //回傳 promise
console.log('result', result)
}
main()
思考過程
沒有細看 console 出來的訊息「undefined」,在 function 執行後產生的意思,其實是在 function 內沒有 return 值,所以在 function 被執行時,會印出 undefined。
後來在 fetch(api200)
改成 return fetch(api200)
就印出來 array 了,後來發現 return response.json()
是在 .then(function)
內的 return
不是在 getData()
的回傳值,所以才會印出 undefined。
碰到的問題二:
What is the difference between JavaScript promises and async await?
碰到問題
dev tool: console
Promise {<pending>}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Object
預期的行為
dev tool: console
{_total: 2392, top: Array(5)}
top: (5) [{…}, {…}, {…}, {…}, {…}]
_total: 2392
__proto__: Object
嘗試過的解決方法
相關程式碼
function getData() {
return fetch(url, {
method: 'GET',
headers: new Headers({
'Accept': acceptHeader,
'Client-ID': clientIdHeader
})
}).then((response) => {
return response.json();
})
}
async function getTop5Games() {
const result = await getData(); //回傳 promise
return result;
}
console.log(getTop5Games());
修改:
async function getTop5Games() {
const result = await getData(); //回傳 promise
console.log(result);
}
getTop5Games()
思考過程
async function--MDN 回傳的是 promise
,所以可以發現在第一部份出錯時,在 async function getTop5Games
return 的是 result
變數,然後再印出來:Promise {<pending>}
,
碰到的問題三:
要如何使用 try catch
的方法,才可以抓出錯誤訊息?以下嘗試了三個方法:
碰到問題
預期的行為
預期只是想測試 API URL 有無錯誤,沒有的話,就繼續往下執行 code。
嘗試過的解決方法
嘗試的解決方法有以下:
- [Failed] 方法一:在 try 放 URL,
fetch
放try catch
之外 - [Failed] 方法二:在
try catch
後加上finally { fetch =>得到 API data}
- [successed] 方法三:在
try
放入要執行的 code,在最後放catch error
##### 嘗試過的解決方法一:
將變數命名拉出來,只在 try 裡面放 API URL(如下圖及 code),並輸入錯誤的 API URL:https://apis.twitch.tv/kraken/games/top?limit=${topGameNumber}
(正確為 api.twitch...,我在 api 後面多加 s,變成錯誤的 API URL)。
輸出結果:
顯示的 error 提示,是在 fetch 裡面印出的的錯誤訊息提示,不是 try catch
印出的。
相關 code:
async function getNavAndStreams() {
const navBarUrl = `https://apis.twitch.tv/kraken/games/top?limit=${topGameNumber}`
try {
navBarUrl
} catch (err) {
console.log('error in the home page:\n', err)
}
const jsonData = await getData(navBarUrl) // GET API: 前五熱門的遊戲 data
嘗試過的解決方法二:
查 MDN 裡 finally
的方法,使用看看,將略過 try catch 的內容,先行執行的 finally
指令放入使用 fetch 發 request 得到 API 的 code。
輸出結果:
還是找不到 jsonData 的值。結果下圖就出現: undefined 看不懂被 try 包住的變數 jsonData,然後想起來變數的 scope 特性:外層看不到內層的變數,內層看的到外層的變數。
相關 code:
const navBarUrl = `https://api.twitch.tv/kraken/games/top?limit=${topGameNumber}`
try {
navBarUrl
} catch (err) {
console.log('error in the home page:\n', err)
} finally {
const jsonData = await getData(navBarUrl) // GET API: 前五熱門的遊戲 data
}
...
嘗試過的解決方法三:
將需要執行的 code 全部包進 try
,最後再 catch(err) {console.log(err)}
錯誤。
輸出結果:將 API 故意輸入成錯誤的 API(https://api.twitchssss.tv...
) 顯示如下圖:
輸出結果:
相關 code:
try {
const navBarUrl = `https://api.twitch.tv/kraken/games/top?limit=${topGameNumber}`
const jsonData = await getData(navBarUrl) // GET API: 前五熱門的遊戲 data
const topFiveGames = await topGamesList(jsonData, topGameNumber) // array(length= 5):前五熱門遊戲名稱的
await dynamicUpdateNavBar(topFiveGames) // JS動態新增到 HTML:導覽列的前五熱門遊戲名稱
await dynamicUpdateH2(topFiveGames) // JS動態新增到 HTML:首頁最熱門遊戲的名稱(heading 2)
// 首頁:20 個實況
const top1StreamsUrl = `${apiUrl}streams?stream_type=live&game=${topFiveGames[0]}` // 準備發 request 的 URL,目的為尋找該遊戲的前20實況台
const jsonStreams = await getData(top1StreamsUrl) // GET API 該遊戲的前 20 實況台資料
await updateLiveStreams(jsonStreams, streamsNumber) // JS動態新增到 HTML:前 20 實況台資料
} catch (err) {
console.log('error in the home page:\n', err)
}
相關程式碼:尚未加入 try catch
前的 code
async function getNavAndStreams() {
// 首頁:從 API 抓取前五熱門遊戲名稱及 top 1
// 並新增至 navbar 與 top 1 遊戲名稱(heading 2)
const navBarUrl = `https://api.twitch.tv/kraken/games/top?limit=${topGameNumber}`
const jsonData = await getData(navBarUrl) // GET API: 前五熱門的遊戲 data
const topFiveGames = await topGamesList(jsonData, topGameNumber) // array(length= 5):前五熱門遊戲名稱的
await dynamicUpdateNavBar(topFiveGames) // JS動態新增到 HTML:導覽列的前五熱門遊戲名稱
await dynamicUpdateH2(topFiveGames) // JS動態新增到 HTML:首頁最熱門遊戲的名稱(heading 2)
// 首頁:20 個實況
const top1StreamsUrl = `${apiUrl}streams?stream_type=live&game=${topFiveGames[0]}` // 準備發 request 的 URL,目的為尋找該遊戲的前20實況台
const jsonStreams = await getData(top1StreamsUrl) // GET API 該遊戲的前 20 實況台資料
await updateLiveStreams(jsonStreams, streamsNumber) // JS動態新增到 HTML:前 20 實況台資料
碰到的問題四:
new Promise
與 fetch
的關聯?要如何一起使用?
問題描述:
因為在影片範例中提到怎麼自己建立一個 promise,加上也有提到是要將作業 twitch 的 XHRHttpRequest 改成 fetch,還要改成使用 promise,所以一開始我在想要怎麼在作業裡面使用到這兩個方法。
疑惑解答:
但是不太瞭解要怎麼使用,所以查到以下這個資料:
- What about "new Promise"? What is it? Do I need it? When?
You need it when you don't have a promise already and you need a promise chain. You don't need it when you have a promise already (such as the one from fetch) and need a promise chain.
From:(JS) Very confused about Promises with fetch
碰到的問題四:
How to Use Fetch with async/await?
問題描述:
要怎麼使用 async/await
來實現非同步的方法?
疑惑解答:
在 How to Use Fetch with async/await? 這篇文章的範例,觀察到 fetch
與使用 async/await
的方法:
- Summary
Calling fetch() starts a request and returns a promise. When the request completes, the promise resolves to the response object. From the response object you can extract data in the format you need: JSON, raw text, Blob.
Because fetch() returns a promise, you can simplify the code by using the async/await syntax: response = await fetch().
From: How to Use Fetch with async/await?
,加上在How to make HTTP requests using Fetch API and Promises 提到了 promise 的意思,執行過程為非同步,替代了使用 callback function 來執行非同步的方式:
What are Promises?
The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
Promises provides us a simpler alternative to executing, composing and managing asynchronous operation compared to the traditional callback-bases approach.
From: How to make HTTP requests using Fetch API and Promises
有了怎麼使用 fetch, await, async
與 promise
的概念,就知道要怎麼寫了,嘗試如下:
async function getNavAndStreams() {
// 首頁:從 API 抓取前五熱門遊戲名稱及 top 1
// 並新增至 navbar 與 top 1 遊戲名稱(heading 2)
try {
const navBarUrl = `https://api.twitchssss.tv/kraken/games/top?limit=${topGameNumber}`
const jsonData = await getData(navBarUrl) // GET API: 前五熱門的遊戲 data
const topFiveGames = await topGamesList(jsonData, topGameNumber) // array(length= 5):前五熱門遊戲名稱的
await dynamicUpdateNavBar(topFiveGames) // JS動態新增到 HTML:導覽列的前五熱門遊戲名稱
await dynamicUpdateH2(topFiveGames) // JS動態新增到 HTML:首頁最熱門遊戲的名稱(heading 2)
// 首頁:20 個實況
const top1StreamsUrl = `${apiUrl}streams?stream_type=live&game=${topFiveGames[0]}` // 準備發 request 的 URL,目的為尋找該遊戲的前20實況台
const jsonStreams = await getData(top1StreamsUrl) // GET API 該遊戲的前 20 實況台資料
await updateLiveStreams(jsonStreams, streamsNumber) // JS動態新增到 HTML:前 20 實況台資料
} catch (err) {
console.log('error in the home page:\n', err)
}
}
碰到的問題五:
箭頭函式簡化