Node.js 的事件驅動編程對於新手來說可能比較棘手,但這並不意味著難以入門。本文將介紹Node.js 的基礎知識,並解釋其流行的原因。
要開始使用Node.js,首先必須了解Node.js 與傳統服務器端腳本環境(如PHP、Python 或Ruby)的區別。
您很可能熟悉異步編程;畢竟,它是AJAX 中的“A”。 Node 中的每個函數都是異步的。因此,所有通常會阻塞線程的操作都使用Promise 在後台執行。這是關於Node 最重要的一點。例如,如果您正在讀取文件系統上的文件,則將使用異步函數。
如果您使用的是某些版本的Node 函數,則使用回調函數,這些函數是在Promise 出現之前設計的。現在大多數Node 函數都有Promise 等效項,因此最好將此處使用的回調函數轉換為基於Promise 的等效項,並比較語法。
使用Node,您必須自己完成很多工作。例如,HTTP 模塊非常精簡且不拘泥於特定風格。這對新手來說可能令人不知所措,但好處是能夠構建高性能的Web 應用(儘管JavaScript 的性能很大程度上歸功於V8 優化的引擎)。一個腳本處理與所有客戶端的所有通信。這大大減少了應用程序使用的資源數量。例如,這是一個簡單的Node.js 應用程序代碼:
const i, a, b, c, max; max = 1000000000; var d = Date.now(); for (i = 0; i <p>以下是使用PHP 編寫的等效代碼:</p><pre class="brush:php;toolbar:false"> $a = null; $b = null; $c = null; $i = null; $max = 1000000000; $start = microtime(true); for ($i = 0; $i <p>現在讓我們看看基準測試數據。下表列出了這兩個簡單應用程序的響應時間(以毫秒為單位):</p><pre class="brush:php;toolbar:false"> const http = require('http');
http 變量。
在上面的代碼中,我們將模塊的名稱傳遞給exports 對象,並使用要公開的代碼片段填充其屬性和方法。考慮以下模塊示例:
exports.area = function (r) { return Math.PI * r ** 2; }; exports.circumference = function (r) { return 2 * Math.PI * r; };
此代碼創建了一個exports 對象。這些函數可以在模塊外部訪問,因為它們是在PI 上定義的,完全受到保護,免受外部干擾。因此,您可以放心,circumference() 將始終按預期工作(只要為import 關鍵字提供值):
// file import myModule from "./myModule.js" // Node 內置/包import http from "http"
在瀏覽器中,ESM 只能使用相對文件路徑進行搜索,如上所示。但是,在Node 中,您可以傳遞沒有node: 前綴的路徑。
但是,以前的方法僅適用於默認導出。如果您使用的是命名導出(稍後將詳細介紹),則需要使用稍微不同的語法。
import { exportOne, exportTwo } from "./myModule.js"
要導出內容,請使用export default 關鍵字。 export 用於命名導出,export default 用於默認導出。命名導出允許您導出不同的內容,並且僅使用其中一個在不同的模塊中使用上面的import 語法。如果您只導出一個內容,則默認導出會更容易。
// 命名導出export function exportOne() { ... } export function exportTwo() { ... } // 默認導出export default function defaultFunction() { ... }
在本教程的其餘部分,我們將使用ESM。
Node 是在Google 的V8 JavaScript 引擎中運行的JavaScript 環境。因此,我們應該遵循我們在客戶端開發中使用的最佳實踐。例如,我們應該避免將任何內容放入全局作用域。但是,這並非總是可能的。 Node 中的全局作用域是(在瀏覽器中為window),您可以通過在聲明變量時省略var 來輕鬆創建函數的全局變量。
自然地,我們需要在編寫和執行應用程序之前安裝Node。如果您使用的是Windows 或macOS,安裝非常簡單;nodejs.org 網站提供了這些操作系統的安裝程序。對於Linux,請使用任何包管理器。例如,如果您使用的是支持apt 的發行版,請打開終端並鍵入:
sudo apt-get update sudo apt-get install node
或:
sudo aptitude update sudo aptitude install node
Node.js 位於sid 存儲庫中;您可能需要將它們添加到您的源列表中:
sudo echo deb https://ftp.us.debian.org/debian/ sid main > /etc/apt/sources.list.d/sid.list
但請注意,在較舊的系統上安裝sid 包可能會破壞您的系統。請小心,並刪除module_name。
當然,我們的第一個Node.js 腳本將打印在控制台中顯示的文本“Hello World!”。
讓我們繼續一個更高級的應用程序;它並不像您想像的那麼複雜。讓我們從以下代碼開始。閱讀註釋,然後閱讀下面的解釋:
// 包含http 模塊。 import { createServer } from "http" // 創建服務器。作為參數傳遞的函數在每次發出請求時都會被調用。 // request 變量保存所有請求參數// response 變量允許您對發送到客戶端的響應執行任何操作。 createServer(function (request, response) { // 在end 事件上附加偵聽器。 // 當客戶端發送所有數據並等待響應時,將調用此事件。 request.on("end", function () { // 將標頭寫入響應。 // 200 是HTTP 狀態代碼(此代碼表示成功) // 第二個參數在對像中保存標頭字段// 我們正在發送純文本,因此Content-Type 應為text/plain response.writeHead(200, { 'Content-Type': 'text/plain' }); // 發送數據並結束響應。 response.end('Hello HTTP!'); }); // 偵聽8080 端口。 }).listen(8080);
這段代碼非常簡單。您可以通過使用response.end() 向客戶端發送更多數據。將此代碼保存為http.js ,然後在控制台中鍵入以下命令:
node http.js
打開瀏覽器並導航到https://www.php.cn/link/7232a90ea7d391905f9ee07bcc7c5967 。您應該在頁面上看到文本Hello HTTP! 。
如前所述,我們必須自己完成Node 中的所有工作,包括解析請求參數。但是,這相當簡單。看看下面的代碼:
// 包含createServer import { createServer} from "http" // 和url 模塊,它在解析請求參數方面非常有用。 url = require("url"); // 創建服務器。 createServer(function (request, response) { // 在end 事件上附加偵聽器。 request.on('end', function () { // 解析請求參數並將它們存儲在_get 變量中。 // 此函數解析來自請求的url 並返回對象表示。 var _get = url.parse(request.url, true).query; // 將標頭寫入響應。 response.writeHead(200, { 'Content-Type': 'text/plain' }); // 發送數據並結束響應。 response.end('Here is your data: ' _get['data']); }); // 偵聽8080 端口。 }).listen(8080);
此代碼使用query 屬性,該屬性檢索URL 的參數。將此文件保存為get.js並使用以下命令執行它:
node get.js
然後,導航到data 參數不會中斷腳本。
要管理Node 中的文件,我們使用fs模塊(核心模塊)。我們分別使用fs.writeFile() 方法讀取和寫入文件。我將在以下代碼之後解釋參數:
// 包含createServer, import { createServer } from "http" // 和fs 函數import { readFile, writeFile } from "fs" // 創建http 服務器。 createServer(function (request, response) { // 在end 事件上附加偵聽器。 request.on("end", function () { // 讀取文件。 readFile("test.txt", 'utf-8', function (error, data) { // 寫入標頭。 response.writeHead(200, { 'Content-Type': 'text/plain' }); // 將從文件中獲得的數字遞增。 data = parseInt(data) 1; // 將遞增的數字寫入文件。 writeFile('test.txt', data); // 使用一些不錯的消息結束響應。 response.end('This page was refreshed ' data ' times!'); }); }); // 偵聽8080 端口。 }).listen(8080);
將此保存為files.js 。在運行此腳本之前,在與files.js相同的目錄中創建一個名為test.txt的文件。
此代碼演示了fs.writeFile() 方法。每次服務器收到請求時,腳本都會從文件中讀取一個數字,遞增該數字,並將新數字寫入文件。 fs.writeFile() 方法接受文件名和數據作為參數。它還接受第三個和第四個參數(兩者都是可選的),分別指定編碼和回調函數。
現在,讓我們使用以下命令運行此腳本:
node files.js
在瀏覽器中以https://www.php.cn/link/7232a90ea7d391905f9ee07bcc7c5967打開它並刷新幾次。現在,您可能會認為代碼中存在錯誤,因為它似乎遞增了兩次。這不是錯誤。每次請求此URL 時,都會向服務器發送兩個請求。第一個請求是由瀏覽器自動發出的,它請求favicon.ico ,當然,第二個請求是針對URL( https://www.php.cn/link/7232a90ea7d391905f9ee07bcc7c5967 )。
即使此行為在技術上不是錯誤,但它也不是我們想要的行為。我們可以通過檢查請求URL 來輕鬆修復此問題。以下是修改後的代碼:
// 包含createServer, import { createServer } from "http" // 和fs 函數import { readFile, writeFile } from "fs" // 創建http 服務器。 createServer(function (request, response) { // 在end 事件上附加偵聽器。 request.on('end', function () { // 檢查用戶是否請求/ if (request.url == '/') { // 讀取文件。 readFile('test.txt', 'utf-8', function (error, data) { // 寫入標頭。 response.writeHead(200, { 'Content-Type': 'text/plain' }); // 將從文件中獲得的數字遞增。 data = parseInt(data) 1; // 將遞增的數字寫入文件。 writeFile('test.txt', data); // 使用一些不錯的消息結束響應。 response.end('This page was refreshed ' data ' times!'); }); } else { // 指示未找到請求的文件。 response.writeHead(404); // 並在不發送任何數據的情況下結束請求。 response.end(); } }); // 偵聽8080 端口。 }).listen(8080);
現在測試它;它應該按預期工作。
大多數傳統的服務器端技術都具有連接到數據庫並查詢數據庫的內置方法。使用Node.js,您必須安裝一個庫。在本教程中,我選擇了穩定且易於使用的node-mysql 。此模塊的全名是mysql@2.0.0-alpha2 (@ 之後的所有內容都是版本號)。打開控制台,導航到您已存儲腳本的目錄,然後執行以下命令:
npm install mysql
這將下載並安裝模塊,它還會在當前目錄中創建node_modules文件夾。現在讓我們看看如何在代碼中使用它;請參見以下示例:
// 包含http 模塊, import { createServer } from "http" // 和您剛剛安裝的mysql 模塊。 import * as mysql from "mysql" // 創建連接。 // 數據默認為新的mysql 安裝,應根據您的配置進行更改。 const connection = mysql.createConnection({ user: "root", password: "", database: "db_name" }); // 創建http 服務器。 createServer(function (request, response) { // 在end 事件上附加偵聽器。 request.on('end', function () { // 查詢數據庫。 connection.query('SELECT * FROM your_table;', function (error, rows, fields) { response.writeHead(200, { 'Content-Type': 'x-application/json' }); // 將數據作為JSON 字符串發送。 // Rows 變量保存查詢的結果。 response.end(JSON.stringify(rows)); }); }); // 偵聽8080 端口。 }).listen(8080);
使用此庫查詢數據庫很容易;只需輸入查詢字符串和回調函數即可。在實際應用程序中,您應該檢查是否存在錯誤(如果發生錯誤則為undefined)並根據查詢的成功或失敗發送響應代碼。另請注意,我們已設置x-application/json,這是JSON 的有效MIME 類型。使用JSON.stringify()
方法將rows 轉換為JSON 結構。
將此文件保存為mysql.js ,然後執行它(如果您已安裝MySQL):
node mysql.js
在瀏覽器中導航到https://www.php.cn/link/7232a90ea7d391905f9ee07bcc7c5967 ,您應該會收到下載JSON 格式文件的提示。
Node.js 需要額外的工作,但快速而強大的應用程序的回報是值得的。如果您不想在最低級別上完成所有工作,您可以隨時選擇一個框架(例如Express)來簡化應用程序的開發。
Node.js 是一項很有前景的技術,也是高負載應用程序的絕佳選擇。微軟、eBay 和雅虎等公司已經證明了這一點。如果您不確定託管您的網站或應用程序,您可以隨時使用廉價的VPS 解決方案或各種基於雲的服務,例如Microsoft Azure 和Amazon EC2。這兩種服務都以合理的價格提供可擴展的環境。
以上是node.js初學者的詳細內容。更多資訊請關注PHP中文網其他相關文章!