演習課 WEEK13


Posted by s103071049 on 2021-07-21

Q1 : 在 week12 [MTR05] Todo list 參考範例 Part4 的影片中看到,todolist 的資料是以 JSON 的格式儲存在資料庫中,想問這做法和另外開 table 專門存 todolist 資料的差異。想儲存 JSON 格式是否用 mongoDB 這類非關聯式資料庫會比較適合呢

A1 : 這是一個偷懶的作法。因為沒有要對她做 query,所以將整包丟進去

  1. 因為沒有正規化,所以無法做 query、更新也不方便。
    你直接存一個欄位,裡面是 json 格式的東西 [{"id":1, "content": "xxx"}]。但硬要做,也可以只是不推薦,因為每做一次就會 pass 一次,會破壞資料庫的正規化。
  2. 存 json 格式可以用 mongoDB

解決方式、

  1. 做正規化存成關聯式資料庫的形狀 : todos 表,有欄位 id, content, isDone

  2. 用 mongoDB 存將整包 JSON 丟進去

How to search JSON data in MySQL?


Q2 : fetch 如果寫了 content-type 為 application/json 為什麼 body 還需要用 JSON.stringify() 去解析,既然是要求 content 為 JSON 為什麼不能直接用物件 {} 的方式帶入 body,謝謝

fetch(url, {
  headers: {
    'Content-Type' : 'application/json'
  },
  body: JSON.stringify({
    username : 'abc'
  })
})

===

你都知道我要帶 json 這樣不是更方便嗎 
fetch(url, {
  headers: {
    'Content-Type' : 'application/json'
  },
  body: {
    username : 'abc'
  }
})

A2 : 因為 fetch 沒有提供這個功能

fetch 是底層的 API,不會幫你做任何變動。他的 body 、header 是獨立分開的,你要傳甚麼 body 你就傳,所以他會用 物件.stringify 的方式變成字串,而不是 json.stringify,他預設裡面會傳一個字串進去。

今天想要有些功能的東西,就用 library,例如 : axios,他底層還是呼叫 fetch,但他會做好 json 轉換。

底層東西就不要隱含過多邏輯操作。因為隱含邏輯在裡面,東西就會變得複雜,細節被藏住外面會不知道你在幹嘛。

這就跟瀏覽器提供的都是比較底層的操作,如果要更方便的,就要自己將他組起來。

Q3 : 既然fetch不管 content type, 那為什麼還要帶 content type ? 是因為還是要跟對方的瀏覽器告知 content type 之類的資訊嗎?

A3 : 跟對方的瀏覽器完全沒有關係 ! 目的是告訴 server 是甚麼格式。少了 content-type 或 body,server 都不知道怎麼解讀

fetch
body 怎麼給跟 content-type 沒有關係
browser => server

Q4 : week12 老師示範 $.ajax 串 api_add_comments.php ,表單 submit 網頁就可以將新增最新留言出現在頁面上了,為什麼需要在監聽事件阻止預設行為又用 .done 重新 append 來顯示最新留言呢 ? 純為了使用者體感嗎 ?

A4 : 對,Ajax 被發明就是為了不要表單換頁跟 server 交換資料。而且,使用 ajax 可以將整個狀態保存起來
既然都不換頁新增評論,現在要換頁就多此一舉了 ! 所以,不換頁新增評論後還需要不換頁將最新評論拿出來。如果今天不用 ajax 每做一次操作就要換一次頁面,整個狀態就沒了! 如果在捷運上網速很慢,換頁就要等頁面所有資源載入一遍,但使用 ajax 就只要等 request 回來。示範也是為了展示使用者體驗。


Q5 : 如果想要提早做 final project 但現在還沒學 react 是建議從後端開始做嗎 還是要學到 react後再做比較好規劃 ?

A5 : 從後端開始,先規劃要做的東西、並將 products 要做的東西規劃、先看 19 週課程、學長姐專案內容。規劃完成後再寫 codes。


Q6 : 不太理解為什麼第四期官網適合用 gulp 而不是 webpack ?

A6 : gulp is task manager (任務管理者)、webpack is a bundler (打包達人)

第四期的官網純靜態,頂多用到 jQuery,因為沒有甚麼需要打包的,所以不用 webpack。第四期官網要做的像是 minify、圖片壓縮,webpack 也剛好可以做,但 gulp 本身就是做這個的。


Q7 : 使用 babel 讓程式碼也可以支援舊瀏覽器,可是這樣轉換後的程式碼可讀性降低很多,一般做 babel 轉換之後,還會保留原始(轉換前)的程式碼來做後續開發維護嗎? 是的話,那寫程式的時候是不是盡量用比較新的語法例如 async 比較好(因為會比 cb 好閱讀)?

A7 : 對 babel 有錯誤理解! 另外,用最新的語法當然比較好,因為可以用 babel 換成舊的。

這個問題類似用 webpack 打包後的程式碼可讀性很差,我會用打包好的 codes 做開發嗎 ? 當然不會 !

app.js (開發) => babel 轉換 
=> dist/app.js 或 output/app.js (放上去空間給使用者使用的,是轉換後的版本)

dist/app.js
dist/app.js.map
兩個搭配一起,用 dev-tool 看就可以看到 app.js
key word : map compile


Q8 : week13 介紹了 SCSS, babel, gulp, webpack ,課程是說有很多套件,所以只介紹幾個常用的。想請教老師還有什麼其他好用的套件嗎?

A8 : 沒有了,這幾個是最常用到的功能。


call back function

call back function 做完甚麼事情再去呼叫這個 function。知道執行順序比較重要。定義沒有到很明確。

Q9 : 為什麼cb沒有被定義但 cb(data) 之後會把 data 帶回去96行那邊再把留言render出來 ?
A9 :

寫法一、 額外宣告函式

function handler(data) {

}

getCommentsAPI(siteKey, lastId, handler)

====

第二種、 將函數直接帶進去裡面

getCommentsAPI(siteKey, lastId, function handler(data) {

})

===

第三種、省略函數的名子

getCommentsAPI(siteKey, lastId, function(data) {

})

===

第四種、箭頭函式

getCommentsAPI(siteKey, lastId, (data) => {

})
===
第五種、最常見,第三個參數是一個函式
箭頭函式只傳一個參數,可以不用括號

getCommentsAPI(siteKey, lastId, data => {

})
function handle() {
  ...
}

function getCommentApi(url, siteKey) {
  // 算 cb
  $.ajax({

  }).done(handle)
  // 不算 cb
  $.ajax({

  }).done( () => {
    handle()
  })
}

Q10 : e.stopPropagation() 是阻止事件的傳遞,目前只了解定義不太會運用,老師可舉範例嗎 e.preventDefault()是預設原本的行為 要怎麼知道目前預設的行為是什麼呢 根據 html標籤嗎 ,例如 form的預設行為是 submit

A10 : 預設行為是根據 html 標籤,會和你的元素有關。當有父子關係,外面需要 click,裡面也需要 click,當點裡面外面也會被觸發。如果不想外面被觸發可以用 e.stopPropagation() 阻止他傳遞。


Q11 : 請問 Async await 這樣把非同步寫成類似同步的樣子是現在主流的寫法嗎 如果是的話代表先前的cb因不好閱讀而逐漸被淘汰嗎

A11 : 對,主流寫法。cb 的問題在於太多層的話很像地獄。用 Async await 除了更好讀外,可以用 try、catch 去抓錯誤。但有些時候還是一定要用到 cb,像 addEventListener

const result = await getCommentsAPI()
const users = await getUsers(id)
const token = await getToken(id)

====

getCommentsAPI(siteKey, lastId, function handler() {
  getUsers(id, function() {
    getToken(id, function() {

    })
  })
})

Q12 : 之後我們還會機會再用到 gulp 跟 webpack 嗎 ?

A12 : gulp 不會 ! webpack week20 react 會默默用到。


callback, Promise, async/await

Q13 : callback, Promise, async/await, 之間的差異

A13 : 對使用者而言,非同步可以用 cb、Promise、async/await 實做。不清楚也沒關係,week20 會有很多 promises。

cb 他回傳的結果我用函式去接

getCommentsAPI(id, function(err, data) {
  if (err) {
    console.log('error')
    return
  }
  console.log(data)
})


寫的人
function getCommentsAPI(id, callback) {
  const xhr = new XMLHttpRequest
  xhr.send()
  xhr.onload = function() {
    callback(null, data)
  }
  xhr.onerror = function() {
    callback('error')
  }
}

===

假設 getCommentsAPI 是 PROMISE

getCommentsAPI(id).then(data => {
  console.log(data)
}).catch(err => {
  console.log('error')
})

除了可以用 promise 的方式拿他,也可以用 async await 的方式拿 promise 的資料


try {
  const data = await getCommentsAPI(id)
  console.log(data)
} catch(err) {
  console.log('error')
}

寫的人
(函式裡的兩個參數,是成功或失敗需要呼叫的
遵守他給的規則,getCommentsAPI 就會是一個 Promise)
const getCommentsAPI = new Promise((resolve, reject) => {
  const xhr = new XMLHttpRequest
  xhr.send()
  xhr.onload = function() {
    resolve(data)
  }
  xhr.onerror = function() {
    reject('error')
  }
})

Q14 : 如果 MySQL 安裝成功,可是用 sequel pro, sequel ace, MySQL workbench 都連接不到資料庫,這樣怎麼辦?
A14 : 連不到跟用甚麼工具無關,要去找資料庫設定。要去找哪段錯誤 !


Q15 : 語法糖的定義可以再講多一點嗎 不是很懂,或是為什麼叫語法糖 ?

A15 : 功能上沒有變,但讓你的寫法變簡單。 async/await 沒有改變 promise 的事實,只是用不同方式將 promise 的結果拿出來。一樣的功能,但寫法更簡單。


GraphQL 介紹

Q16 : GraphQL 是甚麼 ?
A16 : 前端要拿各種 api 並自己組合好,超級麻煩! 用 graphQL palyground 可以找到一些有趣的資料。對前端來說很友善,一個 query 就可以做很多事情,但後端就比較麻煩了。
GraphQL Playground

以臉書舉例她有各式各樣的資訊
messengers
friends
feeds

一個頁面可能要 call 多支 api
getMsgs()
getFriends()
getFeeds
getRecommendations()
...
此外,我今天用 getFriends() 只想拿 name, avatar 但因為裡面資訊很多,所有資料都被丟過來了

facebook homepage

可以只打一支 api 就拿到我要的資料嗎 ?

我的 api 只有一個 endpoint 永遠都用 post 接這支 api,要的內容寫在 body 裡,需要符合特定格式。這整套東西就叫 GraphQL。

由前端跟後端說我要甚麼資料,由後端處理。之前的做法是,後端提供資料給我,我自己再去組裝。

這套最麻煩的是 server,server 要去解析這個 query 語法,

POST/api
{
  messages() {
    name,
    id
  }
  friends() {
    name, 
    avatar
  }
  feeds() {
    content,
    id, 
    author {
      name,
      id
    }
  }
}

#week13 #note







Related Posts

 [ week 1 ] Git 新手入門

[ week 1 ] Git 新手入門

[Week 2] JavaScript - 判斷式、迴圈

[Week 2] JavaScript - 判斷式、迴圈

Vue.js 學習旅程Mile 4 – 模板語法之一:Mustache 語法

Vue.js 學習旅程Mile 4 – 模板語法之一:Mustache 語法


Comments