乐趣区

关于前端:在Deno中构建一个命令行天气预报程序

首发于公众号《前端全栈开发者》,第一工夫浏览最新文章,会优先两天发表新文章。关注后私信回复:大礼包,送某网精品视频课程网盘材料,准能为你节俭不少钱!

在本文中,咱们将通过装置 Deno 运行时,并创立一个命令行天气程序,该程序将把一个城市名称作为参数,并返回将来 24 小时的天气预报。

要为 Deno 编写代码,我强烈建议将 Visual Studio Code 与官网的 Deno 插件一起应用。为了使事件更乏味,咱们将应用 TypeScript 编写应用程序。

装置 Deno

首先,让咱们把 Deno 装置到本地,这样咱们就能够开始编写脚本了。这个过程很简略,因为三大操作系统都有装置脚本。

Windows

在 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

macOS

在 Mac 上,能够将 Brew 与 Deno 一起装置:

brew install deno

装置后

装置过程实现后,你能够通过运行以下命令查看 Deno 是否正确装置。

deno --version

你当初应该看到相似以下内容:

deno 1.2.0
v8 8.5.216
typescript 3.9.2

让咱们为咱们的新我的项目创立一个文件夹(在你的 home 文件夹内,或者任何你喜爱保留代码我的项目的中央)并增加一个 index.ts 文件。

mkdir weather-app
cd weather-app
code index.ts

留神:正如我下面提到的,我在本教程中应用 VS Code。如果你应用的是不同的编辑器,请替换下面最初一行。

获取用户输出

咱们的程序将检索给定城市的天气预报,因而在运行该程序时,咱们须要承受城市名称作为参数。提供给 Deno 脚本的参数以 Deno.args 的模式存在。让咱们把这个变量记录到控制台,看看它是如何工作的。

console.log(Deno.args);

当初,应用以下命令运行脚本:

deno run index.ts --city 杭州 

你应该看到以下输入:

["--city", "杭州"]

只管咱们能够本人解析此参数数组,但 Deno 的规范库包含一个名为 flags 的模块,它将为咱们解决这一问题。要应用它,咱们要做的就是在文件顶部增加一个 import 语句:

import {parse} from  "https://deno.land/std@0.61.0/flags/mod.ts";

留神:规范库模块的文档中的例子会给你一个未版本化的 URL(如 https://deno.land/std/flags/m…,它将始终指向最新版本的代码。在你的导入中指定一个版本是一个很好的做法,以确保你的程序不会被将来的更新所毁坏。

让咱们应用导入的函数将参数数组解析为更有用的内容:

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.ts
Download https://deno.land/std@0.61.0/_util/assert.ts
Check file:///home/njacques/code/weather-app/index.ts
{_: [], city: "杭州" }

每当 Deno 运行脚本时,它都会查看新的 import 语句。任何近程托管的导入都将被下载,编译和缓存以备未来应用。parse 函数为咱们提供了一个对象,该对象具备蕴含咱们输出内容的 city 属性。

留神:如果你因为任何起因须要为一个脚本从新下载导入,你能够运行 deno cache –reload index.ts。

咱们还应该减少对 city 参数的查看,如果没有提供城市参数,则以错误信息退出程序。

if (args.city === undefined) {console.error("No city supplied");
  Deno.exit();}

应用天气 API

咱们将从 tianqiapi.com 获取预报数据。你须要注册一个收费账户,以取得一个 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 appid = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const appsecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

const res = await fetch(`https://yiketianqi.com/api?version=v9&appid=${appid}&appsecret=${appsecret}`);
const data = await res.json();

console.log(data);

Deno 尝试在可能的状况下反对许多浏览器 API,因而在这里咱们能够应用 fetch 而不用导入任何内部依赖项。咱们还利用了对 await 的反对:通常,咱们必须将所有应用 await 的代码包装在 async 函数中,然而 TypeScript 并没有使咱们这样做,这使得代码变得更好了。

如果你当初尝试运行此脚本,则会遇到谬误音讯:

Compile file:///Users/zhangbing/github/CodeTest/Deno/weather-app/index.ts
error: Uncaught PermissionDenied: network access to "https://yiketianqi.com/api?version=v9&appid=xxxxxxxx&appsecret=xxxxxxx", run again with the --allow-net flag
    at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
    at Object.sendAsync ($deno$/ops/dispatch_json.ts:98:10)
    at async fetch ($deno$/web/fetch.ts:296:27)
    at async file:///Users/zhangbing/github/CodeTest/Deno/weather-app/index.ts:13:13

默认状况下,所有 Deno 脚本都在平安的沙箱中运行:它们无权拜访网络,文件系统或诸如环境变量之类的货色。须要为脚本明确授予对其须要拜访的系统资源的权限。在这种状况下,谬误音讯将帮忙咱们理解所需的权限以及如何启用它。

让咱们再次调用脚本,并带有正确的标记:

deno run --allow-net index.ts --city 杭州 

这次,咱们应该从 API 取回 JSON 响应:

{
  cityid: "101210101",
  city: "杭州",
  cityEn: "hangzhou",
  country: "中国",
  countryEn: "China",
  update_time: "2020-08-13 16:51:27",
  data: [
    {
      day: "13 日(星期四)",
      date: "2020-08-13",
      week: "星期四",
      wea: "多云",
      wea_img: "yun",
      wea_day: "多云",
      wea_day_img: "yun",
      wea_night: "多云",
      wea_night_img: "yun",
      tem: "37",
      tem1: "38",
      tem2: "28",
      humidity: "40%",
      visibility: "暂缺",
      pressure: "1002",
      win: ["西南风", "无继续风向"],
      win_speed: "4- 5 级转 <3 级",
      win_meter: "小于 12km/h",
      sunrise: "05:24",
      sunset: "18:43",
      air: "35",
      air_level: "优",
      air_tips: "空气很好,能够外出流动,呼吸新鲜空气,拥抱大自然!",
      alarm: {
        alarm_type: "低温",
        alarm_level: "橙色",
        alarm_content: "杭州市气象台 2020 年 8 月 13 日 9 时 05 分公布低温橙色预警信号:受副热带低压管制,预计明天主城区和钱塘新区最高气温将达 38℃左右,请留神做好防暑降温等工作。(预警信息起源:国家预警信息公布核心)"
      },
      hours: [[Object], [Object],
        [Object], [Object],
        [Object], [Object],
        [Object], [Object],
        [Object], [Object],
        [Object], [Object],
        [Object], [Object],
        [Object], [Object]
      ],
      index: [[Object], [Object], [Object], [Object], [Object], [Object] ]
    },
    ... ...
  ]
}

返回字段的含意能够查看 API 文档。data 数组就是每日数据列表,1- 7 日,共 7 组。每个对象中蕴含气象预警 (alarm)、小时预报 (hours)、生存指数 (index)、空气质量指数 (aqi) 数据。

为了简略起见,咱们只获取几个简略的数据:日期、天气、实时温度空和空气质量等级四个数据,为此须要遍历数组:

const forecast = data.data.map((item) => [
  item.day, // 日期
  item.wea, // 天气
  item.tem, // 实时温度
  item.air_level, // 空气质量等级
]);

如果咱们当初尝试运行脚本,咱们会失去一个编译谬误(如果你应用像 VS 代码这样的 IDE,在键入代码时也会失去这个谬误): 参数 ‘ item’隐式地具备一个‘any’ 类型。

TypeScript 要求咱们通知它该 item 是什么类型的变量,以便晓得咱们是否对它做了任何可能在运行时导致谬误的事件。让咱们增加一个接口,以形容 item 的构造:

interface forecastItem {
  day: string;
  wea: string;
  tem: string;
  air_level: string;
}

让咱们将新类型增加到 map 回调中:

const forecast = data.data.map((item: forecastItem) => [
  item.day, // 日期
  item.wea, // 天气
  item.tem, // 实时温度
  item.air_level, // 空气质量等级
]);

如果你应用的 IDE 反对 TypeScript,它应该可能在你输出时主动实现 item 的类型,这要感激咱们提供的接口类型。

当初运行后果输出如下:

forecast [[ "13 日(星期四)", "多云转晴", "36", "优"],
  ["14 日(星期五)", "晴", "37", ""],
  ["15 日(星期六)", "晴", "37", ""],
  ["16 日(星期日)", "多云转晴", "37", ""],
  ["17 日(星期一)", "晴", "37", ""],
  ["18 日(星期二)", "晴", "37", ""],
  ["19 日(星期三)", "晴", "38", ""]
]

格式化输入

当初咱们有了所需的数据集,接下来让咱们来看一下如何格式化它以便显示给用户。让咱们应用 ascii_table 模块将其显示在整洁的小表中:

import AsciiTable from 'https://deno.land/x/ascii_table/mod.ts';

...

const table = AsciiTable.fromJSON({title: `${args.city} 七日天气预报 `,
  heading: ['日期', '天气', '实时温度', '风', '空气质量', '天气预警'],
  rows: forecast
})

console.log(table.toString())

保留并运行脚本,当初咱们应该曾经对接下来的 7 日内的所选城市进行了格式化并给出了预报:

残缺代码清单

这是一个紧凑的脚本,然而上面是残缺的代码清单,也可去咱们的 Github。

import {parse} from "https://deno.land/std@0.61.0/flags/mod.ts";
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();}

// 你本人的 API 密钥
const appid = "xxxxxxxx";
const apiKey = "xxxxxxxxx";

const res = await fetch(`https://yiketianqi.com/api?version=v9&appid=${appid}&appsecret=${apiKey}`,
);
const data = await res.json();

interface forecastItem {
  day: string;
  wea: string;
  tem: string;
  air_level: string;
}

const forecast = data.data.map((item: forecastItem) => [
  item.day, // 日期
  item.wea, // 天气
  item.tem, // 实时温度
  item.air_level, // 空气质量等级
]);

const table = AsciiTable.fromJSON({title: `${args.city} 七日天气预报 `,
  heading: ["日期", "天气", "温度", "空气质量"],
  rows: forecast,
});

console.log(table.toString());

总结

当初,你有了本人的正在运行的 Deno 命令行程序,该程序将为你提供接下来 7 日天气预报。通过遵循本教程,你当初应该相熟如何启动新程序,从规范库和第三方导入依赖项以及授予脚本权限。

那么,在尝到了为 Deno 编写程序的苦头之后,接下来你应该去哪里呢?你感觉 Deno 如何?


举荐浏览

  • EmailJS:5 步应用 JavaScript 间接从前端发送电子邮件
  • 如何应用 JavaScript 拜访设施前后摄像头
  • 应用 Typescript 和 ES 模块公布 Node 模块
  • Javascript 开发人员偏爱 Deno 而不是 Node 的 5 大起因
  • 如何应用 CSS Paint API 动态创建与分辨率无关的可变背景
  • 这 9 种 Vue 技术你把握了吗?不信你全晓得
  • 2020 年的 12 个 Vue.js 开发技巧和诀窍
  • 在 Vue.js 编写更好的 v -for 循环的 6 种技巧
  • 实战:应用 React Hook 一步一步创立一个可排序表格组件
  • 实战 | HTML 页面生成器:应用 JavaScript 和 Node 创立 CLI
  • 实战 | 从零开始应用 JavaScript 制作本人的命令行 (CLI 工具)
  • 【实战】这个炫酷的播放粒子成果,你也能够学会!应用 Web 动画 API 制作
退出移动版