第一天 - 你在 NodeJS 的第一周
我相信您在开始学习本课程之前已经对 Node.js 有所了解,为了帮助您回忆一下,Node.js 是一个 JavaScript 运行时环境,它基于 Chrome 的 V8 JavaScript 引擎构建。Node.js 采用事件驱动、非阻塞的模型,使其轻量高效。
Node.js 包生态系统 npm 是世界上最大的开源库生态系统。
现在让我们开始第一天的议程。
1. 安装
您可以直接访问Node.js 官方网站,根据您的操作系统下载最新的稳定版本(LTS)。
安装完成后,您可以打开终端/命令提示符,检查它是否正在运行。
$ node --version
// v14.16.1 (in my case)
除了上述方法外,您还可以使用任何编辑器创建一个文件app.js(或任何名称)。
// app.js
console.log("node is working");
现在使用 Node.js 运行此文件。
$ node app.js
// node is working
您已在计算机上安装了 Node.js 🏆
2. 全局对象
安装完 Node.js 后,我们快速了解一下全局对象,这些对象可以直接使用,无需任何第三方导入。这些对象/函数都是 Node.js 内置的。如果您已经使用过 JavaScript,肯定对其中一些对象有所了解,例如(console、setInterval、setTimeout 等)。
JavaScript (window) 与 Node.js 全局对象的主要区别在于,您无法访问与屏幕相关的函数,例如:滚动、样式等。
您可以尝试以下 Node.js 代码示例。
// app.js
setTimeout(() => {
console.log("5 seconds have passed");
}, 5000);
// Run this code again
$ node app.js
另一个很有用的全局对象是 `$_PATH` process,我们将在后续课程中频繁使用它。`$_PATH`process保存着 Node.js 运行进程的最新状态。它允许你读取服务器当前运行的环境,或者在启动服务器时设置自定义环境变量。
常见的使用场景是将凭据存储在其中process,以便稍后在程序中使用。
// Setting process variable
$ export DB_NAME=demo_db
$ export DB_PASSWORD=yes_you_are_right
// Run your app
$ node app.js
// app.js
const {DB_NAME, DB_PASSWORD} = process.env
console.log(DB_NAME); // demo_db
console.log(DB_PASSWORD); // yes_you_are_right
3. 模块 +require()
到目前为止(如上所述),我们把所有内容都写在了一个文件中,这对于练习程序等情况来说很好。但如果你想参与一个实际项目,其中可能涉及其他团队/人员,并且他们也在同一个项目上工作,那么建议你采用模块化的方式。
模块只不过是将你的代码拆分成不同的、可重用的部分的一种方法。
它可以是一个文件,也可以是同一个文件中的一个函数。你一定听说过纯函数式编程的理念,在这种理念中,每个函数都只负责完成一项任务。
举个例子,你想统计length一个数组中的元素个数。
// Create a new file next to your app.js
// count.js
const count = (arr) => {
return arr.length
}
现在你已经count.js完成了这些工作,是时候让它在应用程序中可重复使用了。
在将其称为模块之前,我们需要对
count.js文件进行一些更改。
// count.js
const count = (arr) => {
return arr.length
}
module.exports = count; // It will export this component as a module
既然我们已经count准备好要包含的模块,那就让我们在……中调用它吧app.js。
// app.js
const count = require('./count'); // including `count` function as a module
cosole.log(count([1, 98, 22, 41])) // return: 4
您可以从单个文件中发送多个模块。
// utils.js
const add = (a, b) => {
return a + b;
}
const sub = (a, b) => {
return a - b;
}
const getDatabaseName = () => process.env.DB_NAME;
module.exports = {
add,
sub,
getDatabaseName,
};
// You also change your public function names
module.exports = {
plus: add,
minus: sub,
DBName: getDatabaseName,
};
// app.js
const utils = require("./utils");
console.log(utils.add(1, 2)); // result: 3
console.log(utils.sub(2, 1)); // result: 1
console.log(utils.getDatabaseName()); // result: demo_db
4. 事件发射
与上面定义的模块类似,我们也有一些内置的核心 Node.js 模块可供使用。其中一个示例是该events模块。
click与 JavaScript的事件类似,onChangeNode.js 也能够定义自己的事件,以便在需要时使用。
// custom-events.js
const events = require('events');
const utils = require("./utils");
const eventEmitter = new events.EventEmitter();
eventEmitter.on("showSum", (a, b) => {
console.log(`Sum is: ${utils.add(a, b)}`);
});
module.exports = eventEmitter;
我们的事件发射器模块已经准备就绪,让我们在应用程序中使用它吧。
// app.js
const customEvents = require("./custom-events");
customEvents.emit("showSum", {a: 1, b: 2}); // Sum is: 3
5. 读取/写入/传输文件
学习了 Node.js 中的事件处理之后,让我们快速了解一下 Node.js 核心模块的文件处理fs。
我们先来读取文件以测试fs模块。但首先,我们需要一个文件来读取。让我们先创建一个文件。
读取操作()
// Inside the same directory
$ touch read.txt
$ vim ./read.text // Add some content and save the file.
// app.js
const fs = require("fs");
const readMeFile = fs.readFileSync("./read.txt", "utf-8");
console.log(readMeFile); // File contents
写入操作
// app.js
const fs = require("fs");
const readMeFile = fs.readFileSync("./read.txt", "utf-8");
fs.writeFileSync("./read-new.txt", readMeFile);
上述语句会简单地读取文件的内容,并将其内容read.txt写入另一个文件。read-new.txt
读写文件有两种方式:同步和异步。上面我们使用同步方式读取文件。这种方式会阻止程序在读取完整个文件之前执行。
另一方面,fs.readFile也可以异步读取文件,有时我们也会使用这种方法。
我们快速了解一下异步文件读取操作:
const fs = require("fs");
fs.readFile("./read.txt", "utf-8", (err, data) => {
if(err) {
console.error(err);
}
console.log(data);
});
console.log("Am I first?");
// Result:
// file content
// Am I first?
在上面的示例中,可以看到readFile操作之外的文本首先被记录下来。异步操作在后续操作独立于文件读/写操作时非常有用。
希望您喜欢本系列的开篇之作,敬请期待本系列的后续文章。
祝您阅读愉快!
