fetch 是 JavaScript  ES6 新增的用來執行 Ajax 行為的方法,相比舊版的 XMLHttprequest 不論是閱讀程式碼、或是實際開發都方便不少,而 fetch 其實就是使用 Promise 開發的方法,因此 fetch 語法和 Promise 寫法非常類似,同時可以使用到上個章節提到的  async/await 。
本篇會使用 https://randomuser.me/  來做 ajax 範例。
要使用 fetch 直接使用 fetch()  並帶上網址便可執行 Ajax 行為,上面有提到 fetch 其實就是使用 Promise 開發的方法,因此當 fetch 的 Ajax 成功後,會使用和 Promise 相同使用 .then()  來執行成功的程式碼,失敗則是使用 .catch()  ,比如這個範例:
fetch('https://randomuser.me/api/')
  .then((response) => {
		// 回傳 ReadableStream 物件,可使用 .json() 等等方法,取得對應資料。
    return response.json()
  }).then((data) => {
    console.log(data)
  }).catch((err) => {
    console.log('錯誤:', err)
})
當 fetch  成功後,會回傳 ReadableStream 物件,這時會使用不同的方法取得對應資料,上面範例就使用 json()  來將 ReadableStream 轉換成一個實際可使用的物件, 其他方法還有:
詳細部分可參考 MDN 文件介紹:https://developer.mozilla.org/zh-TW/docs/Web/API/Response
上面也有提到 fetch 也可以搭配  async/await ,以上面範例來製作 async/await 版本:
async function useAjax() {
	try{
	  const ajax = await fetch('https://randomuser.me/api/');
	  const data = await ajax.json();
		console.log(data)
	} catch(error) {
    console.log('錯誤:', err)
  }
}
useAjax()
在實做中 Ajax 行為往往不會向上面範例這麼簡單,通常還需要設定一些  headers、 methods  等等的設定,若要設定這些功能會在 fetch()  中第二個參數做詳細設定,而第二個參數必需寫成物件,比如這個範例:
fetch('http://httpbin.org/post', {
	  // Ajax 行為改為 Post
      method: 'POST',
      // headers 加入 json 格式
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        test: '123',
      })
    })
      .then((response) => {
        return response.json()
      }).then((Data) => {
        console.log(Data)
      }).catch((err) => {
        console.log('錯誤:', err)
      })
值得一提的是,使用 post 行為時 ,我們通常會帶上一些資料給後端,和其他包裝好的 Ajax 框架不同, fetch  會需要手動將資料轉成字串。
在實做中一定會碰到需要有順序的執行 Ajax 的狀況,而這邊也模擬一些狀況,使用 fetch 做 Ajax 串接,並搭配前幾個章節介紹的 async/await 、 Promise.all() 來製作可以按順序來執行 Ajax 的程式碼:
這種狀況使用 async/await 或是 原生 Promise 鏈式寫法都能達成,這邊以 async/await 為範例:
async function useAjax() {
  try {
    const ajax1 = await fetch('https://randomuser.me/api/')
    const data1 = await ajax1.json()
    console.log('data1', data1)
    const ajax2 = await fetch('https://randomuser.me/api/')
    const data2 = await ajax2.json();
    console.log('data2', data2)
  } catch (error) {
    console.log('錯誤:', err)
  }
}
useAjax()
這種狀況其實繼續使用  async/await  來寫也可以達成,不過會變成:
執行 Ajax1 ⇒ Ajax1 完成 ⇒ 執行 Ajax2 ⇒ Ajax2 完成 ⇒ 執行 Ajax3
這樣就會浪費較多時間再等待 Ajax 回傳,所以比較好的方法就是使用 Promise.all() 搭配 async/await ,或是單純 Promise.all() 加上 Promise 鏈式寫法,這邊以 Promise.all() 搭配 async/await  為範例。
async function useAjax() {
  try {
    const ajax1 = fetch('https://randomuser.me/api/')
    const ajax2 = fetch('https://randomuser.me/api/')
    const [res1, res2] = await Promise.all([ajax1, ajax2])
    const data1 = await res1.json()
    const data2 = await res2.json()
    console.log('data1', data1)
    console.log('data2', data2)
    const ajax3 = await fetch('https://randomuser.me/api/')
    const data3 = await ajax3.json()
    console.log('data3', data3)
  } catch(error) {
     console.log('錯誤:', err)
  }
}
useAjax()