原文地址 Medium - How To Master Async/Await With This Real World Examplejavascript
Async/Await
是一種書寫異步代碼的新方式。它是構建與 promises 之上的,因此也具備非阻塞特性。java
最大的區別就在於異步代碼的樣式和行爲看起來都比較像同步代碼,這也是其強大之處。ios
以前咱們寫異步代碼通常都使用的是 callbacks 和 promises。npm
setTimeout(() => {
console.log('This runs after 1000 milliseconds.');
},1000);
複製代碼
在回調函數中嵌套的回調函數很快就會讓你的代碼變成這樣: axios
這種狀況就會讓你的代碼變的很難理解和維護。const promiseFunction = new Promise((resolve, reject) => {
const add = (a, b) => a + b;
resolve(add(2, 2));
});
promiseFunction.then((response) => {
console.log(response);
}).catch((error) => {
console.log(error);
});
複製代碼
promiseFunction 返回一個 Promise,表明該函數的過程。resolve 函數表明 Promise 實例執行完畢。api
而後咱們能夠在 promise 函數上調用 .then()
和 .catch()
方法:.then()
做用是 promise 決議後執行你傳入的回調函數,.catch()
的做用是程序出錯時執行你傳入的那個回調函數。promise
Async
函數Async
函數提供給咱們一個簡明的語法,讓咱們可以用更少的代碼來實現咱們原本用 promise 獲得的相同結果。能夠說 Async
就是 promise 的語法糖了。異步
Async
函數的建立時經過在函數聲明語句以前加上 async 關鍵字,示例以下:async
const asyncFunction = async () => {
// Code
}
複製代碼
Async
異步函數可經過 await
來暫停,該關鍵字只能用在 Async
函數內部。每當函數執行完畢,await 返回的是任何 async 函數會返回的東西。函數
下面是 promise 和 async/await 的區別:
// Async/Await
const asyncGreeting = async () => 'Greetings';
// Promises
const promiseGreeting = () => new Promise(((resolve) => {
resolve('Greetings');
}));
asyncGreeting().then(result =>
console.log(result)
);
promiseGreeting().then(result =>
console.log(result)
);
複製代碼
async/await 看起來和同步代碼類似,於是更容易理解。
基礎知識講完了,如今咱們來說個實在例子。 (實際上下面這個項目中的 API 如今已經不能用了,好像是已經變成收費的了,免費部分你們能夠自行查閱並實現功能,這個例子就看看 async/await 的使用便可)
這裏將用一個簡單又實用的小項目來提升你對 Async/Await 的總體認知。
程序接收咱們想要轉換的兩種貨幣代碼以及錢數,而後基於一些 API 獲取的數據輸出正確的匯率。使用的 API 以下:
對於新手來講,建立一個新的目錄,在該目錄上打開命令行執行 npm init
,確認跳過全部的步驟,而後使用 npm i --save axios
命令安裝 axios 。新建一個文件命名爲 currency-converter.js
。
Async/Await
吧咱們項目的目標是要寫三個異步函數,第一個函數做用是拿到貨幣數據,第二個函數做用是拿到城市數據,第三個函數做用是將前面獲取到的數據整理到一塊兒並格式化輸出給用戶。
該異步函數將接受兩個參數,fromCurrency 和 toCurrency。 如今咱們須要獲取數據了,使用 async/await 時咱們能夠直接把獲取到的數據賦值給一個變量:
const getExchangeRate = async (fromCurrency, toCurrency) => {
const response = await axios.get('http://data.fixer.io/api/latest?access_key=[yourAccessKey]&format=1');
}
複製代碼
咱們能夠直接把響應的數據中匯率信息直接賦給一個變量:
const rate = response.data.rates;
複製代碼
因爲 API 提供的數據都是基於歐元來轉換的,因此這裏咱們建立一個變量 euro
,用 1 除以咱們想要轉換的貨幣:
const euro = 1 / rate[fromCurrency];
複製代碼
最後,咱們能夠用咱們想轉換的貨幣乘以 euro
來得到兌換匯率:
const exchangeRate = euro * rate[toCurrency];
複製代碼
整個函數代碼以下:
建立一個接收貨幣代碼爲參數的異步函數:
const getCountries = async (currencyCode) => {}
複製代碼
而後經過 API 獲取數據:
const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);
複製代碼
而後遍歷數據返回country.name
:
return response.data.map(country => country.name);
複製代碼
最終代碼以下:
try...catch
處理異常第一個函數:
const getExchangeRate = async (fromCurrency, toCurrency) => {
try {
const response = await axios.get('http://data.fixer.io/api/latest?access_key=f68b13604ac8e570a00f7d8fe7f25e1b&format=1');
const rate = response.data.rates;
const euro = 1 / rate[fromCurrency];
const exchangeRate = euro * rate[toCurrency];
return exchangeRate;
} catch (error) {
throw new Error(`Unable to get currency ${fromCurrency} and ${toCurrency}`);
}
};
複製代碼
第二個函數同理:
const getCountries = async (currencyCode) => {
try {
const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);
return response.data.map(country => country.name);
} catch (error) {
throw new Error(`Unable to get countries that use ${currencyCode}`);
}
};
複製代碼
如今咱們能夠調用這個函數了:
convertCurrency('USD', 'HRK', 20).then((message) => {
console.log(message);
}).catch((error) => {
console.log(error.message);
});
複製代碼
查看程序輸出: