(Day26) 使用 fetch 串接 Ajax

前言

fetch 是 JavaScript ES6 新增的用来执行 Ajax 行为的方法,相比旧版的 XMLHttprequest 不论是阅读程序码、或是实际开发都方便不少,而 fetch 其实就是使用 Promise 开发的方法,因此 fetch 语法和 Promise 写法非常类似,同时可以使用到上个章节提到的 async/await

本篇会使用 https://randomuser.me/ 来做 ajax 范例。

fetch 基本介绍

要使用 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 转换成一个实际可使用的物件, 其他方法还有:

  • json()
  • text()
  • bolb
  • arrayBuffer()
  • redirect()
  • clone()
  • error()

详细部分可参考 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()

如何设定 fetch ?

在实做中 Ajax 行为往往不会向上面范例这麽简单,通常还需要设定一些 headersmethods 等等的设定,若要设定这些功能会在 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 会需要手动将资料转成字串。

fetch 搭配 async/await 范例

在实做中一定会碰到需要有顺序的执行 Ajax 的状况,而这边也模拟一些状况,使用 fetch 做 Ajax 串接,并搭配前几个章节介绍的 async/awaitPromise.all() 来制作可以按顺序来执行 Ajax 的程序码:

  • 状况一:需等 Ajax1 完成後,才执行 Ajax2

这种状况使用 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()
  • 状况二: 需等 Ajax1、Ajax2 完成後,才执行 Ajax3

这种状况其实继续使用 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()

参考文献


<<:  第 11 集:浅谈 Sass

>>:  【Day10】表单 Form:受控元件 Controlled Component

【Day2】声音的一些基本介绍

声音这东西实在是太自然了,所以我们很少去思考这东西的本质到底是什麽 简单的来复习一下声音是什麽,你...

从 React 开始,让你的网页material-ui起来 [Day 3] 排版布局Container

网页的开始 於布局排版 现在的年代 也需要RWD适合部分版型 所以我们就由布局开始吧 常常会看到一种...

ASP.NET MVC 从入门到放弃(Day18)-MVC检视(View)介绍

接下来讲讲View 部分... 在控制器的ActionResult Index() 上方可点选右键新...

Day 15 - Ping Sweeping 与 Port Scanning

出於书本 Chapter 8. Network Infrastructure 撑过一半了加油加油加油...

操作授权 (Authorization to Operate:ATO)

-NIST SDLC 和 RMF RMF:授权系统( Authorize System) 授权是授...