原文地址: How To Master Async/Await With This Real World Example
原文作者: Adrian Hajdin
译者: arzh
推荐理由: ES6中的异步方法已经成为开发中不可或缺的一部分,本篇文章可以让你从实际开发中快速了解及学习Async/Await
的使用
目录
- 介绍(callbacks,promise,async/await)
- 现实案例--从两个API接收异步数据的货币转换器
进入正文之前
在写这篇文章的同时,我还创建了一个 YouTube 视频! 你可以边看边写代码。我建议你先阅读这篇文章,然后随着视频一起编写代码。
介绍
Async/Await
是一种编写异步代码的新方法。 它建立在 promise 之上,因此,它也是非阻塞的。
最大的区别在于 Async/Await
的使用使异步代码看起来有点像同步代码。 这就是它的所有力量所在。异步代码以前通常有 callbacks 和 promise 两种选择。
callbacks函数的使用
setTimeout(() => {
console.log('This runs after 1000 milliseconds.');
}, 1000);
复制代码
callbacks函数的问题--回调地狱
在回调函数中嵌套回调函数很快就会变成这样:
回调被嵌套在其他回调中有好几层之深,可能使理解和维护代码变得困难。
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() 函数:
- then — 运行 promise 函数完成时传递给它的回调
- 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中的数据输出正确的汇率。
在这个应用程序中,我们将从两个异步源接收数据:
-
货币层 - currencylayer.com - 您需要免费注册,以便使用API访问密钥。 此API将为我们提供计算货币之间汇率所需的数据。
-
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];
复制代码
最后,函数应该是这样的
第二个函数--异步接收国家数据
我们将创建一个将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);
复制代码
最后,该函数应如下所示:
第三个也是最后一个功能 - 将它们合并在一起
我们将创建一个异步函数,它将 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 来处理错误情况
我们需要在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);
});
复制代码
你将收到的输出
这就是全部啦
你一路坚持到最后,如果你在这个过程中遇到困难,请随意查看这个仓库上的代码。
同时也可以在YouTube上查看,因为我刚刚创建了一个频道! 点击这里,有很多有趣的东西即将到来!