本文已搬家到筆者自己的部落格嘍,有興趣的可以點這個連結~
昨天的文章介紹了 $.ajax()
這個用來進行 AJAX 的 API ,但 $.ajax()
其實有蠻多瓶頸的並不是每種 非同步 的狀況都適用,舉例來說:我今天有三個 API 要同時發送待全部都回傳成功後再一併顯示,這種情況用 $.ajax()
就比較難處理,所以筆者今天就是要來介紹另一種用來處理 非同步 的方法: Promise 。
在前面的文章有提到,其實 Promise
是在 ES6 的時候才正式被 JavaScript 納入為基本 API ,可是 ES6 是在2015年才發表,在2015年之前的工程師又是如何利用 Promise
來處理比較複雜的 非同步 呢?
其實 Promise
有一個規範標準叫:Promise/A+,之後在2013年的時候有一位大大發明了bluebird, bluebird 實現了 Promise/A+ 的標準,大家不妨可以點擊那個超連結去看一下裡面的 API ,可以發現 bluebird
的 API 跟現在的 ES6 Promise 操作方法幾乎一模一樣, ES6 Promise 可是說是 bluebird 改良版阿!於是現在比較少人再用 bluebird
都直接寫 Promise
了, JavaScript 真是英明阿!
在開始介紹一些基本操作之前先來講講兩種初始化 Promise
物件的方法吧!
// 初始化一個新的Promise物件
let promise = new Promise((resolve, reject) => {
// if success -> resolve data
resolve(data)
// if error -> reject error
reject(err)
})
我們可以發現在 new Promise()
的括號裡面要寫一個 callback function ,而這個 callback function 有兩個參數一個是 resolve
另一個是 reject
這兩個代表什麼呢?
resolve
代表操作成功,並將括號內的值回傳回去。
reject
代表操作失敗,並結束操作。
resolve()
以及 reject()
做個結合吧!其實這兩種寫法就是 new Promise()
的簡寫。
// 省略 new Promise的過程,直接 resolve(1)
let promise = Promise.resolve(1)
// 正常寫法
let promise = new Promise((resolve, reject) => {
resolve(1)
})
一般來說 Promise
的流程會長成底下這張圖。
大家有沒有發現在上圖中有 fulfill 以及 reject 這兩個路線,其實這個代表的是 Promise
的狀態。
代表操作成功所以對應到 resolve()
。
代表操作失敗所以對應到 reject()
。
在講完基本觀念與流程之後接下來講點 Promise
的基本操作吧! Promise
的基本操作就跟程式的 try
、 catch
很像。
當 Promise
狀態為 fulfill 時,就可以用 Promise.then()
來操作 resolve()
的回傳值。
當 Promise
狀態為 reject 時,就可以用 Promise.catch()
來操作 reject()
的錯誤值。
溫馨小提醒:不管是
Promise.then()
還是Promise.catch()
都會回傳Promise
物件喔!而且Promise.then()
以及Promise.catch()
括號內都要寫 callback funciton 喔!
講完基礎操作接下來講點進階操作吧!還記得前言提到的一次發送多個請求待全部請求都完成後再一併處理,這種時候就必須要用到 Promise
一些比較進階的操作啦!
Promise.all()
可以想成是一個一個 Promise
的集合,所以操作方法也跟一般的 Promise
一樣,最主要的功能就是等到括號內所有的 Promise
其狀態都是 fulfill 後才會開始執行,回傳值也會是個 Promise
物件,而 Promise.all()
的寫法如下。
let p1 = Promise.resolve(3)
let p2 = 1337
let p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo')
})
Promise.all([p1, p2, p3]).then(values => {
console.log(values) // [3, 1337, "foo"]
})
講了這麼多 Promise
的操作,接著來提一下在昨天提到的 callback hell 問題吧!
Promise
自所以可以有效防止 callback hell 的發生就是來自 Promise.then()
,透過 Promise.then()
可以有效的串接一連串具有 關聯性 的 AJAX ,就像下圖這樣。
所以未來要發生 callback hell 的機率幾乎等於0了,感謝 Promise
讚嘆 Promise
XD
axios 是個以 Promise
為主用來進行前後端溝通的好用 API ,既然是用來進行前後端溝通,想必又跟昨天介紹的 http method 有關聯了,沒錯!其實 axios 就是利用 http method 來進行前後端溝通,而 axios 厲害的地方就在於他會將後端回傳的資料包裝成 Promise
物件給前端操作,所以之後可以利用 Promise.then()
以及 Promise.catch()
來操作回傳的資料非常方便。
在開始使用 axios 之前要記得先在 codepen 的 JavaScript 設定上面先引用 axios 喔!
axios 基本操作有以下幾種:
發送 GET 的請求應用於從後端取得資料。
發送 POST 的請求用於提交資料至後端。
發送 PATCH 的請求用於套用資料至後端修改。
發送 DELETE 的請求用於刪除後端指定資料。
今天介紹了 Promise
這個用來處理 非同步 相當好用的物件,也介紹了 axios 這個 promise base 的 API , Promise
可以說是 非同步 必會的一種方法,大家以後如果要寫任何的前後端溝通不妨可以試試看筆者提供的方法來操作,而今天的小練習就只是把昨天的 $.ajax()
稍微改成 axios 提供給讀者們參考, 非同步實作 到這邊就告一個段落了,這算是一個蠻不好理解的觀念,如果讀者有任何問題都歡迎在底下留言給我,我都會一一解答喔!