在本文中,我將通過安裝Deno執行時,並建立一個命令列天氣程式,該程式將把一個城市名稱作為引數,並返回未來24小時的天氣預報。
要為Deno編寫程式碼,我強烈建議將Visual Studio Code與官方的Deno外掛一起使用。為了使事情更有趣,我們將使用TypeScript編寫應用程式。
安裝Deno首先,讓我們把Deno安裝到本地,這樣我們就可以開始編寫指令碼了。這個過程很簡單,因為三大作業系統都有安裝指令碼。
/ Windows /
在Windows上,你可以從PowerShell安裝Deno:
iwr /file/2020/08/22/20200822182949_1625.jpg.ps1 -useb | iex
/ Linux /
在Linux終端上,可以使用以下命令:
curl -fsSL /file/2020/08/22/20200822182949_1626.jpg.sh | sh
/ macOS /
在Mac上,可以將Brew與Deno一起安裝:
brew install deno
安裝後
安裝過程完成後,你可以通過執行以下命令檢查Deno是否正確安裝。
deno --version
你現在應該看到類似以下內容:
deno 1.2.0v8 8.5.216typescript 3.9.2
讓我們為我們的新專案建立一個資料夾(在你的home資料夾內,或者任何你喜歡儲存程式碼專案的地方)並新增一個 index.ts 檔案。
mkdir weather-appcd weather-appcode 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/[email protected]/flags/mod.ts";
注意:標準庫模組的文件中的例子會給你一個未版本化的URL(如https://deno.land/std/flags/mod.ts),它將始終指向最新版本的程式碼。在你的匯入中指定一個版本是一個很好的做法,以確保你的程式不會被未來的更新所破壞。
讓我們使用匯入的函式將引數陣列解析為更有用的內容:
const args = parse(Deno.args);
我們還將修改指令碼來列印新的 args 變數,看看是什麼樣子的。所以現在你的程式碼應該是這樣的:
import { parse } from "https://deno.land/[email protected]/flags/mod.ts";const args = parse(Deno.args);console.log(args);
現在,如果使用與以前相同的引數執行指令碼,則應該看到以下輸出:
Download https://deno.land/[email protected]/flags/mod.tsDownload https://deno.land/[email protected]/_util/assert.tsCheck 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/[email protected]/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(`/file/2020/08/22/20200822182954_1627.jpg data = await res.json();console.log(data);
Deno嘗試在可能的情況下支援許多瀏覽器API,因此在這裡我們可以使用 fetch 而不必匯入任何外部依賴項。我們還利用了對await的支援:通常,我們必須將所有使用 await 的程式碼包裝在 async 函式中,但是TypeScript並沒有使我們這樣做,這使得程式碼變得更好了。
如果你現在嘗試執行此指令碼,則會遇到錯誤訊息:
Compile file:///Users/zhangbing/github/CodeTest/Deno/weather-app/index.tserror: Uncaught PermissionDenied: network access to "/file/2020/08/22/20200822182954_1628.jpg 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。(私信回覆關鍵字:“deno-weather”獲取完整原始碼)
import { parse } from "https://deno.land/[email protected]/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( `/file/2020/08/22/20200822182958_1629.jpg 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如何?
相關閱讀:
作者簡介:Web前端工程師,全棧開發工程師、持續學習者。
私信回覆:大禮包,送某網精品視訊課程網盤資料,準能為你節省不少錢!
#Deno#