如何掌握异步/等待语法:一个真实的例子

这是Adrian Hajdin的文章的译文,该文章已发布在freeCodeCamp网站上。 在作者的指导下,作者清楚而简洁地说明了异步/等待的优势,并在一个具体示例中展示了如何使用此语法。



注意...

我不仅写了这篇文章,还在YouTube上创建了一个视频!

观看时,您可以按照视频和节目中的说明进行操作。 我建议您先阅读本文,然后再在视频过程中编写代码。

视频链接: 在这个真实的项目中学习异步/等待

引言


异步/等待是一种编写异步代码的新方法。 该语法建立在promise之上,因此不会阻塞。

与创建异步代码的其他方法的不同之处在于,在外观和行为上,通过async / await实现的异步代码类似于同步代码。 这就是他的优势。

组织异步代码的先前方法是回调和Promise。

回调函数的作用


setTimeout(() => { console.log('This runs after 1000 milliseconds.'); }, 1000); 

回调函数问题-臭名昭著的回调地狱


当您将回调函数彼此附加时,代码将很快开始如下所示:


回调地狱

回调地狱

在这种情况下,回调被嵌套在多个级别的其他回调中,这使得难以理解和管理代码。

行动承诺


 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()
然后 -启动完成诺言时传递的回调。
catch-发生错误时启动通过的回调。

异步功能


异步函数为我们提供了简洁明了的语法 ,使我们可以编写更少的代码,并获得与使用promise相同的结果。 异步不过是诺言的语法糖。

通过在函数声明之前添加async关键字来创建异步函数,例如:

 const asyncFunction = async () => { // Code } 

可以使用await 暂停异步功能, await是仅在async函数内使用的关键字。 Await返回异步函数执行时返回的所有内容。

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中的数据发布正确的汇率。

在此应用程序中,我们将从两个异步源获取数据:

  1. 货币层-https : //currencylayer.com-您需要免费注册才能使用API​​访问密钥。 他将为我们提供计算汇率所需的数据。
  2. 休息国家-http : //restcountries.eu/-此API将提供有关我们可以在哪里使用我们刚将钱转入的货币的信息。

首先,创建一个新文件夹并运行npm init ,跳过所有步骤并通过键入npm i -- save axios安装npm i -- save axios 。 创建一个名为currency-converter.js的新文件。

首先输入以下内容来请求axios: const axios = require('axios');

让我们深入了解异步/等待


我们的目标是使程序具有三个功能。 不是一两个,而是三个异步函数 。 第一个功能将接收有关货币的数据,第二个功能将接收有关国家/地区的数据,第三个功能将在一个地方收集此信息并以有序方式将其显示给用户。

第一个功能是异步接收货币数据

我们将创建一个异步函数,该函数将包含两个参数-fromCurrency和toCurrency。

 const getExchangeRate = async (fromCurrency, toCurrency) => {} 

现在您需要获取数据。 使用异步/等待,您可以将数据直接分配给变量。 不要忘记注册并输入您的密码。

 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; 

由于一切都是从欧元转换的,因此下面我们将创建一个称为欧元的变量,该变量等于我们要从中进行货币转移的货币的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); 

结果,该函数应如下所示:



第三个也是最后一个功能-我们将所有内容组合在一起
我们将创建一个异步函数,该函数将包括fromCurrencytoCurrency和sum作为参数:

 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 / 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的支持,因为我最近刚刚在YouTube上创建了一个频道! 点击这里 -很快很多有趣的事情会出现在这里! :)

您还可以观看我在Mongoose网站上创建的教程。

Source: https://habr.com/ru/post/zh-CN438318/


All Articles