作者:Nilson Jacques
转发链接:https://www.sitepoint.com/deno-build-command-line-weather-app/
前言如果您一直在关注有关Deno 的介绍性 文章,那么您可能有兴趣尝试编写第一个程序。在本文中,我们将逐步安装Deno运行时,并创建一个命令行气象程序,该程序将城市名称作为参数并返回接下来24小时的天气预报。
要为Deno编写代码,我强烈建议将Visual Studio Code与官方的Deno插件一起使用。为ios天气预报源码了使事情更有趣,我们将使用TypeScript编写应用程序。
github : https://github.com/denoland/vscode_deno
安装Deno首先,让我们在本地安装Deno,以便我们开始编写脚本。该过程非常简单,因为所有三个主要操作系统都有安装程序脚本。
视窗在Windows上,您可以从PowerShell安装Deno:
iwr https://deno.land/x/install/install.ps1 -useb | iex的Linux在Linux终端上,可以使用以下命令:
curl -fsSL https://deno.land/x/install/install.sh | sh苹果系统在Mac上,可以将Brew与Deno一起安装:
brew install deno安装后安装过程完成后,可以通过运行以下命令来检查Deno是否已正确安装:
deno --version您现在应该看到类似以下内容:
deno 1.2.0v8 8.5.216typescript 3.9.2让我们为新项目创建一个文件夹(在您的主文件夹内,或您希望保留编码项目的任何地方)并添加一个index.ts文件:
mkdir weather-appcd weather-appcode index.ts注意:如上所述,本教程使用的是VS Code。如果您使用其他编辑器,请替换上面的最后一行。
获取用户输入我们的程序将检索给定城市的天气预报,因此在运行该程序时,我们需要接受城市名称作为参数。提供给Deno脚本的参数以形式提供Deno.args。让我们将此变量注销到控制台以查看其工作方式:
console.log(Deno.args);现在,使用以下命令运行脚本:
deno run index.ts --city London您应该看到以下输出:
[ "--city", "London" ]尽管我们可以自己解析此参数数组,但Deno的标准库包括一个名为flags的模块,它将为我们解决这一问题。要使用它,我们要做的就是在文件顶部添加一个import语句:
import { parse } from "https://deno.land/std@0.61.0/flags/mod.ts";注意:文档中标准库模块的示例为您提供ios天气预报源码了未版本化的URL(例如https://deno.land/std/flags/mod.ts),该URL 始终指向最新版本的代码。最好在导入中指定一个版本,以确保程序不会被将来的更新所破坏。*
让我们使用导入的函数将arguments数组解析为更有用的内容:
const args = parse(Deno.args);我们还将更改脚本以注销新args变量,以查看其外观。所以现在您的代码应如下所示:
import { parse } from "https://deno.land/std@0.61.0/flags/mod.ts";const args = parse(Deno.args);console.log(args);现在,如果使用与以前相同的参数运行脚本,则应该看到以下输出:
Download https://deno.land/std@0.61.0/flags/mod.tsDownload https://deno.land/std@0.61.0/_util/assert.tsCheck file:///home/njacques/code/weather-app/index.ts{ _: [], city: "London" }每当Deno运行脚本时,它都会检查新的import语句。任何远程托管的导入都将被下载,编译和缓存以备将来使用。该parse函数为我们提供了一个对象,该对象具有city包含输入的属性。
注意:如果出于某种原因需要重新下载脚本的导入文件,可以运行deno cache --reload index.ts。
我们还应该为该city参数添加检查,如果未提供该参数,则退出并显示错误消息:
if (args.city === undefined) { console.error("No city supplied"); Deno.exit();}与Weather API交谈我们将从OpenWeatherMap获取我们的预报数据。您需要注册一个免费账户,以获得API密钥。我们将使用他们的5天预报API,将城市名称作为参数传递给它。
让我们添加一些代码以获取预测并将其注销到控制台,以查看得到的结果:
import { parse } from "https://deno.land/std@0.61.0/flags/mod.ts";const args = parse(Deno.args);if (args.city === undefined) { console.error("No city supplied"); Deno.exit();}const apiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';const res = await fetch(`https://api.openweathermap.org/data/2.5/forecast?q=${args.city}&units=metric&appid=${apiKey}`);const data = await res.json();console.log(data);Deno尝试在可能的情况下支持许多浏览器API,因此在这里我们可以使用fetch而无需导入任何外部依赖项。我们还利用了支持的顶级await:通常我们不得不包装任何代码,使用await中的async功能,但打字稿并不能让我们做到这一点,这使得代码更好一点。
如果尝试立即运行此脚本,则会遇到错误消息:
Check file:///home/njacques/code/weather-app/index.tserror: Uncaught PermissionDenied: network access to "https://api.openweathermap.org/data/2.5/forecast?q=London&units=metric&appid=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", run again with the --allow-net flag at unwrapResponse ($deno$/ops/dispatch_json.ts:42:11) at Object.sendAsync ($deno$/ops/dispatch_json.ts:93:10) at async fetch ($deno$/web/fetch.ts:266:27) at async index.ts:12:13默认情况下,所有Deno脚本都在安全的沙箱中运行:它们无权访问网络,文件系统或诸如环境变量之类的东西。需要明确授予脚本访问脚本所需的系统资源的权限。在这种情况下,错误消息将帮助我们了解所需的权限以及如何启用它。
让我们使用正确的标志再次调用脚本:
deno run --allow-net index.ts --city London这次,我们应该从API取回JSON响应:
{ cod: "200", message: 0, cnt: 40, list: [ { dt: 1595527200, main: { temp: 22.6, feels_like: 18.7, temp_min: 21.04, temp_max: 22.6, pressure: 1013, sea_level: 1013, grnd_level: 1011, humidity: 39, temp_kf: 1.56 }, weather: [ [Object] ], clouds: { all: 88 }, wind: { speed: 4.88, deg: 254 }, visibility: 10000, pop: 0, sys: { pod: "d" }, dt_txt: "2020-07-23 18:00:00" }, ... ], city: { id: 2643743, name: "London", coord: { lat: 51.5085, lon: -0.1257 }, country: "GB", population: 1000000, timezone: 3600, sunrise: 1595477494, sunset: 1595534525 }}您可以查看响应中返回的内容的全部详细信息,但我们主要感兴趣的是中的预测数据数组list。数组中的每个对象都包含一个时间戳记(dt),一个包含main大气条件(温度,湿度,压力等)详细信息的对象,以及一个weather包含带有预测天气描述的对象的数组。
我们将遍历main数组以获取预测时间,温度和天气状况。让我们从限制仅覆盖24小时周期的记录数开始。免费计划提供给我们的预测数据仅每三个小时提供一次,因此我们需要获取八条记录:
const forecast = data.list.slice(0, 8)我们将映射每个预测项,并返回我们感兴趣的数据数组:
const forecast = data.list.slice(0, 8).map(item => [ item.dt, item.main.temp, item.weather[0].description,]);如果我们现在尝试运行脚本,则会收到编译错误(如果您使用的是类似VS Code的IDE,则在键入代码时也会显示此错误):参数'item'隐含一个'任何类型。
TypeScript要求我们告诉它变量的类型item,以便知道我们是否正在使用它做任何可能在运行时导致错误的事情。让我们添加一个接口,以描述的结构item:
interface forecastItem { dt: string; main: { temp: number; }; weather: { description: string; }[];}请注意,我们在此不描述对象的所有属性,而仅描述我们实际要访问的属性。在我们的情况下,我们知道我们想要哪些属性。
让我们将新类型添加到map回调中:
const forecast = data.list.slice(0, 8).map((item: forecastItem) => [ item.dt, item.main.temp, item.weather[0].description,]);如果您使用的是具有TypeScript支持的IDE,则item由于我们提供的接口类型,它应该能够在您键入时自动完成的属性。
创建服务类创建输出接口格式化输出现在我们有了所需的数据集,下面让我们来看一下如何很好地格式化以显示给用户。
首先,让我们将时间戳记值转换为人类可读的日期。如果我们查看Deno的第三方模块列表并搜索“ date”,我们可以在列表中看到date-fns。我们可以使用此处的链接将要使用的功能导入Deno应用程序:
import { fromUnixTime, format } from "https://deno.land/x/date_fns@v2.15.0/index.js";现在,我们可以通过fromUnixTime函数传递时间戳,以获取一个Date对象,然后将该对象传递给以format获取我们想要的日期字符串:
format(fromUnixTime(item.dt), "do LLL, k:mm", {})格式字符串do LLL, k:mm将为我们提供以下格式的日期:“ 7月24日,13:00”。
注意:我们将传递一个空对象作为第三个参数,以format完全使IDE警告有关预期数量的参数的警告消失。没有它,代码仍然可以正常运行。
在此过程中,让我们将温度值四舍五入到小数点后一位,并添加一个单位指示符:
`${item.main.temp.toFixed(1)}C`现在,我们已将预测数据格式化并准备显示,让我们使用ascii_table模块将其显示在整洁的小表中:
import AsciiTable from 'https://deno.land/x/ascii_table/mod.ts';...const table = AsciiTable.fromJSON({ title: `${data.city.name} Forecast`, heading: [ 'Time', 'Temp', 'Weather'], rows: forecast})console.log(table.toString())保存并运行脚本,现在我们应该已经对接下来的24小时进行了格式化,并给出了所选城市的天气预报:
.--------------------------------------------.| London Forecast ||--------------------------------------------|| Time | Temp | Weather ||-----------------|-------|------------------|| 23rd Jul, 19:00 | 17.8C | light rain || 23rd Jul, 22:00 | 16.8C | light rain || 24th Jul, 1:00 | 16.0C | broken clouds || 24th Jul, 4:00 | 15.6C | light rain || 24th Jul, 7:00 | 16.0C | broken clouds || 24th Jul, 10:00 | 18.3C | scattered clouds || 24th Jul, 13:00 | 20.2C | light rain || 24th Jul, 16:00 | 20.2C | light rain |'--------------------------------------------'完整的代码清单这是一个紧凑的脚本,但是下面是完整的代码清单:
import { parse } from "https://deno.land/std@0.61.0/flags/mod.ts";import { fromUnixTime, format,} from "https://deno.land/x/date_fns@v2.15.0/index.js";import AsciiTable from "https://deno.land/x/ascii_table/mod.ts";const args = parse(Deno.args);if (args.city === undefined) { console.error("No city supplied"); Deno.exit();}const apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";const res = await fetch( `https://api.openweathermap.org/data/2.5/forecast?q=${args.city}&units=metric&appid=${apiKey}`,);const data = await res.json();interface forecastItem { dt: string; main: { temp: number }; weather: { description: string }[];}const forecast = data.list.slice(0, 8).map((item: forecastItem) => [ format(fromUnixTime(item.dt), "do LLL, k:mm", {}), `${item.main.temp.toFixed(1)}C`, item.weather[0].description,]);const table = AsciiTable.fromJSON({ title: `${data.city.name} Forecast`, heading: ["Time", "Temp", "Weather"], rows: forecast,});console.log(table.toString());摘要现在,您有了自己的正在运行的Deno命令行程序,该程序将为您提供接下来24小时的天气预报。通过遵循本教程,您现在应该熟悉如何启动新程序,如何从标准库和第三方导入依赖项以及授予脚本权限。
因此,在喜欢为Deno编写程序的过程中,下一步应该去哪里ios天气预报源码?我绝对建议您通读手册,以了解有关各种命令行选项和内置API的更多信息
作者:Nilson Jacques
转发链接:https://www.sitepoint.com/deno-build-command-line-weather-app/
相关文章
本站已关闭游客评论,请登录或者注册后再评论吧~