[譯] 如何在實際開發案例中掌握 Async/Await

arzh發表於2019-02-25

原文地址: How To Master Async/Await With This Real World Example
原文作者: Adrian Hajdin
譯者: arzh
推薦理由: ES6中的非同步方法已經成為開發中不可或缺的一部分,本篇文章可以讓你從實際開發中快速瞭解及學習 Async/Await 的使用

目錄

  1. 介紹(callbacks,promise,async/await)
  2. 現實案例--從兩個API接收非同步資料的貨幣轉換器

進入正文之前

在寫這篇文章的同時,我還建立了一個 YouTube 視訊! 你可以邊看邊寫程式碼。我建議你先閱讀這篇文章,然後隨著視訊一起編寫程式碼。

視訊連線: Learn Async/Await in This Real World Project

介紹

Async/Await 是一種編寫非同步程式碼的新方法。 它建立在 promise 之上,因此,它也是非阻塞的。

最大的區別在於 Async/Await 的使用使非同步程式碼看起來有點像同步程式碼。 這就是它的所有力量所在。非同步程式碼以前通常有 callbackspromise 兩種選擇。

callbacks函式的使用

setTimeout(() => {
  console.log('This runs after 1000 milliseconds.');
}, 1000);
複製程式碼

callbacks函式的問題--回撥地獄

在回撥函式中巢狀回撥函式很快就會變成這樣:

[譯] 如何在實際開發案例中掌握 Async/Await

回撥被巢狀在其他回撥中有好幾層之深,可能使理解和維護程式碼變得困難。

promise的使用

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 例項發出訊號,告知它已完成。

然後我們可以在該 promise 函式中呼叫 then() 以及 catch() 函式:

  1. then — 執行 promise 函式完成時傳遞給它的回撥
  2. catch — 執行 promise 函式錯誤時傳遞給它的回撥

Async函式

Async 函式為我們提供了一種乾淨簡潔的語法,使我們能夠編寫更少的程式碼來實現與 promise 相同的結果。Async 只不過是 promise 的語法糖

Async 函式是通過在函式宣告之前加上單詞 async 來建立的

const asyncFunction = async () => {
  // Code
}
複製程式碼

Async 函式可以使用 await 暫停,該關鍵字只能在 Async 函式中使用。 Await 返回 async 函式完成時返回的任何內容。

這是 promise 和 Async/Await 之間的區別

// Async / Await
const asyncGreeting = async () => 'Greetings';

// Promise
const promiseGreeting = () => new Promise(((resolve) => {
  resolve('Greetings');
}));
asyncGreeting().then(result => console.log(result));
promiseGreeting().then(result => console.log(result));
複製程式碼

Async/Await 看起來類似於同步程式碼,同步程式碼更容易理解。

現在我們已經介紹了基礎知識,讓我們轉到我們現實世界的例子吧!

貨幣轉換器

專案的說明與設定

在本教程中,我們將構建一個簡單但有教育意義且有用的應用程式,它將提高你對 Async/Await 的整體瞭解

該程式將接受我們想要轉換的貨幣程式碼,以及金額。 之後,程式將根據API中的資料輸出正確的匯率。

在這個應用程式中,我們將從兩個非同步源接收資料:

  1. 貨幣層 - currencylayer.com - 您需要免費註冊,以便使用API​​訪問金鑰。 此API將為我們提供計算貨幣之間匯率所需的資料。

  2. Rest Countries - restcountries.eu/ - 此API將向我們提供有關我們在哪裡可以使用我們剛剛轉換資金的貨幣的資訊。

剛開始,建立一個新目錄並執行 npm init,跳過所有步驟,並通過鍵入 npm i --save axios 來安裝 axios。 建立一個名為 currency-converter.js 的新檔案。

首先,輸入命令:

const axios = require('axios')
複製程式碼

讓我們深入瞭解 Async / Await

這個程式的目標是有三個非同步函式。第一個函式將獲取關於貨幣的資料。第二個函式是獲取關於國家的資料。第三個函式將這些資訊收集到一個地方,並很好地輸出給使用者。

第一個函式--非同步接收貨幣資料

我們將建立一個非同步函式,它將接受兩個引數,fromCurrency和tocurrency。

const getExchangeRate = async (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');
}
複製程式碼

來自響應的資料在response.data.rates下可用,因此我們可以將其放入響應中的變數

const rate = response.data.rates;
複製程式碼

由於所有資料都是從歐元轉換而來,我們將建立一個名為euro的變數,它將等於我們要轉換的(1 / 貨幣)

const euro = 1 / rate[fromCurrency];
複製程式碼

為了獲得匯率,我們可以將歐元乘以我們想要轉換的貨幣

const exchangeRate = euro * rate[toCurrency];
複製程式碼

最後,函式應該是這樣的

[譯] 如何在實際開發案例中掌握 Async/Await

第二個函式--非同步接收國家資料

我們將建立一個將currencyCode作為引數的非同步函式

const getCountries = async (currencyCode) => {}
複製程式碼

如前所述,我們將獲取資料並將其分配給一個變數

const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);
複製程式碼

然後,我們將對映資料併為每個資料返回 country.name

return response.data.map(country => country.name);
複製程式碼

最後,該函式應如下所示:

[譯] 如何在實際開發案例中掌握 Async/Await

第三個也是最後一個功能 - 將它們合併在一起

我們將建立一個非同步函式,它將 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}`;
複製程式碼

將上述所有程式碼合併一起應該是這樣的

[譯] 如何在實際開發案例中掌握 Async/Await

新增 try / catch 來處理錯誤情況

我們需要在try中包裝所有邏輯,如果有錯誤則捕獲錯誤

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);
  });
複製程式碼

你將收到的輸出

[譯] 如何在實際開發案例中掌握 Async/Await

這就是全部啦

你一路堅持到最後,如果你在這個過程中遇到困難,請隨意檢視這個倉庫上的程式碼。

同時也可以在YouTube上檢視,因為我剛剛建立了一個頻道! 點選這裡,有很多有趣的東西即將到來!

相關文章