ECMAScript 之 Asynchronous
栏目: JavaScript · 发布时间: 6年前
内容简介:ECMAScript 對 Asynchronous 總共有 Promise、Generator 與 Async Await 三種支援,其中 Generator 屬於較進階的應用,主要是在寫 library,但 Promise 與 Async Await 則非常重要,寫 application 也很常用到。ECMAScript 2015 (Promise)ECMAScript 2017 (Async Await)
ECMAScript 對 Asynchronous 總共有 Promise、Generator 與 Async Await 三種支援,其中 Generator 屬於較進階的應用,主要是在寫 library,但 Promise 與 Async Await 則非常重要,寫 application 也很常用到。
Version
ECMAScript 2015 (Promise)
ECMAScript 2017 (Async Await)
API
productApi.js
import axios from 'axios'; import { API } from '../environment'; export default { fetchProducts: () => axios.get(`${API}/products`), };
實務上我們會將 API 部分另外寫在 api
目錄下,且另外寫 fetchXXX()
method,但 axios.get()
回傳的到底是什麼型別呢?
是 ECMAScript 2015 新的 Promise
型別。
Promise
由於 Asynchronous 在所有 Synchronous 執行完才會執行,因此對於 AJAX 回傳的資料,對於 Synchronous 而言,屬於一種 未來值
。
也就是 AJAX 所回傳的資料,將來一定會有,但具體時間未知,只能先回傳 Promise
物件給你,一旦 AJAX 抓到資料,你就可以用 Promise 去換真實的資料。
就類似你去麥當勞買漢堡,錢都給了,但漢堡還沒做好,但未來一定會有,也是 未來值
,因此店員會給你 取餐單
,將來你可以用 取餐單
去換漢堡。
取餐單
就是 Promise。
mounted() { const response = res => this.products = res.data; const error = e => console.log(e); const done = () => console.log('finally'); productApi .fetchProducts() .then(response) .catch(error) .finally(done); },
fetchProducts()
會回傳 Promise
物件,該物件總共有 3 個 operator (也是 Higher Order Function)。
- then() :傳入要獲取 AJAX 資料的 function,當 AJAX 抓到資料後,會自己執行 function
- catch() :傳入若 AJAX 錯誤所執行的 function,當 AJAX 出錯時,會自己執行 function
- finally() :傳入 AJAX 最後所執行的 function,當 AJAX 執行完正,會自己執行 function
finally()
目前在 ECMAScript 定義為 stage 4,也就是即將 ECMAScript 正式定義,重要是 Babel 已經率先支援,因此可安心使用
Async Await
async mounted() { try { const response = await productApi.fetchProducts(); this.products = response.data; } catch (err) { console.log(err); } finally { console.log('finally'); } },
Promise 屬於 FP 觀念下的產物 (也就是 Monad Pattern),若你習慣 Imperative 思維,也可以透過 Async Await
將 Asynchronous 寫的很 Synchronous。
將 function 前面宣告 async
,表示此為 Asynchronous Function,也就是內部將使用 await
。
response
為 productApi.fetchProducts()
所回傳的 Promise,是 未來值
, 觀念上
會 await 等 response
成真後才會繼續執行。
因為看起來很像 Synchronous 寫法,因此可以使用原本的 try catch finally
。
Async Await 只是程式碼看起來很像 Synchronous,但起本質仍然是 Asynchronous,因為 await 一定要對方回傳 Promise 才能使用,所以是百分之百的 Syntax Sugar Async Await 來自於 C# 5,在 ECMAScript 2017 正式定案,Babel 也完美支援
Why Promise ?
由 JavaScript 的 Event Loop Model 可知,有三種屬於 Asynchronous:
- DOM
- AJAX (XMLHttpRequest)
- setTimeout()
由於前端一定要使用 AJAX 呼叫 API,這屬於 Asynchronous 行為,會被安排在 Callback Queue ,等 Synchronous 執行完,最後才執行 Asynchronous。
在 ES5 之前,若 Asynchronous 之間有相依的先後關係,在 jQuery + Callback 只能這樣寫:
$.get('/products', (err, res) => { if (err) console.log(err); else { const product = ret.json(); $.get('/product/${ product[0].id}', (err, res) => { if (err) console.log(err); else { const item = res.json(); console.log(item); } }); } });
這就是有名的 Callback Hell :
- 很容易寫出巢狀很深的 code 難以維護
- 每個 Callback 都要自己維護 Exception
fetch('/products') .then(res => res.json()) .then(product => fetch('/products/${ prdouct[0].id}')) .then(res => res.json()) .then(item => console.log(item)); .catch(e => console.log(e));
使用 Promise 後:
then()
Callback 雖然也能解決 Asynchronous,但會造成 Callback Hell,應盡量避免使用,且隨著 ECMAScript 2015 將 Promise 定為標準,越來越多 Library 直接回傳 Promise
型別 (Axios、Protractor …),且 Async Await 也是基於 Promise 技術,所以 Promise 已經成為不能不會的東西
Conclusion
語意
Sample Code
完整的範例可以在我的 GitHub 上找到
Reference
以上所述就是小编给大家介绍的《ECMAScript 之 Asynchronous》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法:C语言实现
塞奇威克 / 机械工业出版社 / 2006-9 / 69.00元
本书是Sedgewick彻底修订和重写的C算法系列的第一本。全书分为四部分,共16章,第一部分“基础知识”(第1-2章)介绍基本算法分析原理。第二部分“数据结构”(第3-5章)讲解算法分析中必须掌握的数据结构知识,主要包括基本数据结构,抽象数据结构,递归和树。一起来看看 《算法:C语言实现》 这本书的介绍吧!