說明: 我翻譯本身讀過的文章,僅僅只是我做爲一個新手的一種學習方式。不少專業化的表達可能不是很是準確!文章中或許有翻譯錯誤的地方,若是你看到了,但願能夠在評論中指出,我會及時修正。對於大佬的你請直接忽視跳過,一樣是小白的你,能夠考慮看看。固然若是有能力,我強烈建議你直接看原文前端
在寫這篇文章的同時,我還錄製了一個相關的視頻,已上傳到 Youtube。 你能夠邊看視頻邊敲代碼,我建議你先看下視頻,而後再以這篇文章爲引導本身練習下代碼。ios
視頻地址:Learn Async/Await in This Real World Projectgit
Async/Await 是一種創建在 promises 基礎上的,書寫異步代碼的新方式,因此它也是非阻塞的。github
與咱們以前異步編程所使用到的回調函數和 promises 相比較,最大的區別就是 async/await 使咱們的異步代碼看起來就像同步代碼同樣,這也正是它的厲害之處。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 函數表示任務已經完成。api
而後,咱們就能夠在 promiseFunction 函數的基礎上調用 then()
和 catch()
方法。數組
then: Promise 成功後執行的回調函數。
catch: 當遇到了錯誤後執行的回調函數。promise
Async函數爲咱們提供了簡潔的語法,咱們能夠經過它實現與 Promise 相同的效果,可是代碼量會減小不少。其實底層原理上,async 不過是 promises 的語法糖而已。
在普通的函數聲明前加上 async 關鍵字,咱們就建立了一個 async 函數:
const asyncFunction = async () => {
// Code
}
複製代碼
異步函數使用 await 表達式能夠暫停函數的執行,await 關鍵字只能在 async 函數中使用,它會返回 Promise 對象的處理結果。
promises 和 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 更易於咱們理解,由於它看起來像同步代碼。
前面咱們已經介紹過這些基礎知識了,如今咱們來看看在現實開發中怎麼使用!
在下面的教程中,咱們將建立一個簡單實用,並且頗有學習意義的應用程序,相信會加深你對 Async/Await 理解
咱們將原始貨幣代碼和想要獲得的貨幣代碼,以及金額輸入程序,而後程序會調用相關的 API,最後將正確的匯率顯示出來
在這個程序中,咱們將從如下兩個 API 異步獲取數據:
首先,建立一個新目錄並運行 npm init
初始化項目,接下里咱們選擇默認值,跳過全部步驟,而後再輸入 npm i——save axios
安裝 axios。在當前文件夾內建立一個 currency-convert .js
的文件。
在 currency-convert .js
文件中,咱們先經過 require
語法引入 axios
const axios = require(‘axios’);` 複製代碼
這個程序中,咱們須要三個異步函數,第一個函數用來獲取關於貨幣的數據;第二個函數用來獲取關於國家的數據;第三個函數用來將全部信息集中起來並展現給用戶看
咱們建立一個接收兩個參數(fromCurrency 和 toCurrency)的異步函數。
const getExchangeRate = async (fromCurrency, toCurrency) => {}
複製代碼
如今咱們獲取數據,而後經過使用 async/await,能夠直接將咱們想要的數據賦值給變量。調用接口以前別忘了要註冊帳號,才能得到 API access key
const getExchangeRate = async (fromCurrency, toCurrency) => {
const response = await axios.get('http://data.fixer.io/api/latest? access_key=[yourAccessKey]&format=1');
}
複製代碼
咱們能夠經過 response.data.rates
來提取咱們想要的數據,而後咱們將它賦值給一個變量 rate
:
const rate = response.data.rates;
複製代碼
由於全部的數據都是從歐元轉換過來的,咱們能夠建立一個變量 euro
,它的值等於:
const euro = 1 / rate[fromCurrency];
複製代碼
最後,咱們能夠用歐元乘以咱們要兌換的貨幣來獲得匯率:
const exchangeRate = euro * rate[toCurrency];
複製代碼
最終的函數看起來像這樣:
建立一個異步函數,接收 currencyCode 做爲參數
const getCountries = async (currencyCode) => {}
複製代碼
和以前同樣,獲取數據,而後將其賦值給一個變量:
const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);
複製代碼
而後經過數組 map 方法將 country.name
提取出來,映射爲一個新的數組:
return response.data.map(country => country.name);
複製代碼
最終代碼:
建立一個異步函數,接收 fromCurrency, toCurrency, amount 三個參數:
const convert = async (fromCurrency, toCurrency, amount) => {}
複製代碼
第一步,獲取貨幣數據:
const exchangeRate = await getExchangeRate(fromCurrency, toCurrency);
複製代碼
第二步,獲取國家數據:
const countries = await getCountries(toCurrency);
複製代碼
第三步,將轉換後的金額賦值給一個變量
const convertedAmount = (amount * exchangeRate).toFixed(2);
複製代碼
最後,將數據輸出給用戶:
return `${amount} ${fromCurrency} is worth ${convertedAmount} ${toCurrency}. You can spend these in the following countries: ${countries}`;
複製代碼
最後完整的代碼:
咱們將程序的邏輯用 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);
});
複製代碼
你會看到下面的結果:
很不錯,你堅持到了最後!若是在學習過程當中遇到了困惑的地方,你能夠參考這個倉庫裏的代碼。若是你有任何問題,能夠在下面留言。你也可關注個人 Youtube 專欄,我會帶來更多幹貨給你們!