ECMAScript 之 Asynchronous
栏目: JavaScript · 发布时间: 7年前
内容简介: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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
HTTP Essentials
Stephen A. Thomas、Stephen Thomas / Wiley / 2001-03-08 / USD 34.99
The first complete reference guide to the essential Web protocol As applications and services converge and Web technologies not only assume HTTP but require developers to manipulate it, it is be......一起来看看 《HTTP Essentials》 这本书的介绍吧!
XML 在线格式化
在线 XML 格式化压缩工具
RGB CMYK 转换工具
RGB CMYK 互转工具