В этой статье я установлю среду выполнения Deno и создам программу погоды из командной строки, которая примет название города в качестве аргумента и вернет прогноз на следующие 24 часа.
Для написания кода для Deno я настоятельно рекомендую использовать Visual Studio Code с официальнойПлагин Denoиспользовать вместе. Чтобы было интереснее, мы напишем наше приложение на TypeScript.
Установить Дено
Во-первых, давайте установим Deno локально, чтобы мы могли начать писать скрипт. Этот процесс очень прост, потому что три основные операционные системы имеют сценарии установки.
Windows
В Windows вы можете установить Deno из PowerShell:
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
Давайте создадим папку для нашего нового проекта (внутри вашей домашней папки или там, где вы хотите хранить свои проекты кода) и добавим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-адрес (например,Не слишком ленивый/физический магазин/флаги/нет…
Давайте используем импортированную функцию, чтобы преобразовать массив аргументов во что-то более полезное:
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 запускает сценарий, он проверяет наличие новых операторов импорта. Любой удаленный импорт будет загружен, скомпилирован и кэширован для будущего использования.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 杭州
На этот раз мы должны получить ответ JSON от API:
{
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;
}
Давайте добавим новый тип в обратный вызов карты:
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, что делать дальше? Что вы думаете о Дено?