一、note.js简介


二、JS发展历史

三、TS语言

四、学习内容

五、学习环境
六、代码
6.1 01-导入机制.js
/**
* 创建一个简单的 HTTP 服务器,监听指定主机和端口。
* 当收到请求时,返回状态码 200 和纯文本内容 "Hello World"。
*/
const { createServer } = require('node:http');
// 定义服务器监听的主机地址
const hostname = '127.0.0.1';
// 定义服务器监听的端口号
const port = 3000;
/**
* 创建 HTTP 服务器实例。
* @param {Function} callback - 请求处理回调函数
* @param {Object} req - HTTP 请求对象
* @param {Object} res - HTTP 响应对象
*/
const server = createServer((req, res) => {
// 设置响应状态码为 200(成功)
res.statusCode = 200;
// 设置响应头,指明内容类型为纯文本
res.setHeader('Content-Type', 'text/plain');
// 结束响应并发送正文内容
res.end('Hello World');
});
/**
* 启动服务器并开始监听连接。
* @param {number} port - 监听端口
* @param {string} hostname - 监听主机地址
* @param {Function} callback - 服务器启动完成后的回调函数
*/
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});



6.2 02-自定义导入.js
01-log.js
// ==========================================
// 1. Named Export (命名导出)
// ==========================================
// 作用:导出一个或多个特定的函数或变量。
// 特点:导入时,必须使用与导出时完全相同的名称(即 { log })。
export function log(str) {
// 获取当前时间并转换为本地时间字符串格式 (例如: "2023/10/27 10:00:00")
const timestamp = new Date().toLocaleString();
// 使用模板字符串将时间戳和传入的内容拼接,并在控制台打印
console.log(`${timestamp} ${str}`);
}
// ==========================================
// 2. Default Export (默认导出)
// ==========================================
// 作用:每个模块只能有一个默认导出。通常用于导出模块的主要功能。
// 特点:导入时,可以随意自定义名称(不需要花括号),例如 import MyLog from './log'。
/*
// export default function log(str) {
// const timestamp = new Date().toLocaleString();
// console.log(`${timestamp} ${str}`);
// }
*/
02-自定义模块导入.js
// --- 1. 命名导入 (Named Import) ---
// 阿米解说:这里我们要从 './log.js' 文件里把之前导出的 `log` 函数"抓"过来。
// 注意看那个花括号 {},它就像是一个精准的抓取器,必须和导出时的名字一模一样才行哦!
import { log } from './log.js';
// 阿米解说:既然把 `log` 函数请过来了,那我们就赶紧用用看吧!
// 在控制台打印一句问候语。
log('Hello, Node.js!');
// --- 2. 默认导入 (Default Import) ---
// 阿米解说:如果对方使用的是 `export default` 导出的话,我们就不需要花括号啦。
// 而且这时候你可以给它起任何你喜欢的名字(比如叫 myLog、abc 都可以),因为它就是那个"唯一"。
// (注:这段代码被注释掉了,因为 log.js 里目前主要展示的是命名导出)
// import log from './log.js'; // 假设 log.js 里用的是 export default function...
// log('Hello, Node.js!'); // 同样可以运行


6.3 03-函数匿名函数箭头函数.js
// ==========================================
// 01-方式 1:函数声明 (Function Declaration)
// ==========================================
// 语法结构:function 函数名(参数1, 参数2) { 代码块 }
function add(x, y) {
// return 关键字用于将计算结果"返回"给调用者
// 如果没有 return,函数执行后默认返回 undefined
return x + y;
}
// ==========================================
// 函数的调用 (Function Invocation)
// ==========================================
// 通过 函数名() 来触发执行,括号内传入具体的数值(实参)
console.log(add(10, 10));
// 这里的执行流程是:
// 1. 调用 add(10, 10),此时 x=10, y=10
// 2. 函数内部计算 10 + 10,得到 20
// 3. return 20,将 20 返回出来
// 4. console.log 接收到返回值,在控制台打印出 20

// ==========================================
// 02-方式 2 匿名函数
// ==========================================
// // 函数变量
// // 函数表达式
// 1. 定义部分
const fAdd = function (x, y) {
return x + y;
}
// 2. 调用部分
console.log(fAdd(20, 20));

//03- 方式 3:使用 Function 构造函数创建函数
// 注意:在实际开发中非常少见,通常用于动态生成代码的特殊场景
// 1. 定义部分
// new Function(arg1, arg2, ..., functionBody)
// - 前面的参数 ("x", "y") 是字符串形式的形参名
// - 最后一个参数 ("return x + y;") 是字符串形式的函数体代码
const fObject = new Function("x", "y", "return x + y;");
// 2. 调用部分
// 像普通函数一样使用变量名加括号进行调用
console.log(fObject(30, 30)); // 输出结果: 60

// 04-匿名函数自启动
// 整体结构:console.log( 函数定义 ( 参数 ) );
console.log((function (x, y) {
// 1. 函数体内部:接收 x 和 y,计算它们的和并返回
return x + y;
})(40, 40));
// ^^^^^^^^^^
// 2. 这里的括号表示"立即执行"上面的函数
// 3. 40, 40 是传递给 x 和 y 的实际参数

// 05-箭头函数
// 【旧写法】标准的函数表达式
// const fAdd = function (x, y) {
// return x + y;
// }
// 【新写法】箭头函数
// 语法结构:(参数) => { 函数体 }
const fArrow = (x, y) => x + y;
// 调用函数并打印结果
console.log(fArrow(50, 50)); // 输出: 100

6.4 04-回调函数.js
// 1. 定义两个基础函数(和你图片里的一样)
const fAdd = function(x, y) {
return x + y;
};
const fMinus = function(x, y) {
return x - y;
};
// 2. 定义一个"高阶函数" (处理者)
// 注意第三个参数 callback,它是一个占位符,准备接收传进来的函数
function calculate(a, b, callback) {
console.log("开始计算...");
// 【关键点】在这里,我们不是自己写加法或减法,
// 而是调用传进来的那个函数!这就是"回调"。
const result = callback(a, b);
console.log("计算结束,结果是:" + result);
}
//01-回调函数
- 使用回调函数
// 我们把 fAdd 这个函数本身(不加括号)作为参数传进去
calculate(10, 5, fAdd);
// 输出:
// 开始计算...
// 计算结束,结果是:15

6.5 05-promise-then异步机制.js
01-同步执行(Synchronous)
// 1. 定义一个模拟"读取文件"的函数
// 这是一个普通的同步函数,它会立即执行并返回结果
function readfile(filename) {
// 第一步:打印日志,告诉用户正在处理哪个文件
console.log('正在读取文件: ' + filename);
// 第二步:模拟读取过程(这里简化为直接拼接字符串)
// 关键点:return 语句会立即把结果交还给调用者
return '文件 ' + filename + ' 读取完成';
}
console.log('--- 程序开始 ---');
// 【第 1 个任务】
// 1. 调用 readfile('file1.txt')
// 2. 进入函数内部 -> 打印 "正在读取..." -> 返回 "文件 file1.txt 读取完成"
// 3. 将返回值赋值给 result1
// 注意:在这一步彻底结束前,下面的代码完全不会运行
const result1 = readfile('file1.txt');
// 【第 2 个任务】
// 只有当上面 result1 拿到值后,才会执行这一行
// 再次进入函数 -> 打印 -> 返回 -> 赋值给 result2
const result2 = readfile('file2.txt');
// 【第 3 个任务】
// 同理,必须等 result2 完成后才执行
const result3 = readfile('file3.txt');
// 【收尾工作】
// 只有当上面三个任务全部串行执行完毕后,才会打印这句话
console.log('所有文件读取完成');

// 02- 异步方式 (使用 Promise)
// 定义一个模拟异步读取文件的函数
function readfile_async(filename) {
// 【核心】返回一个新的 Promise 对象
// Promise 接收一个执行器函数作为参数,该函数包含两个回调:
// resolve: 任务成功时调用,用于传递结果
// reject: 任务失败时调用,用于传递错误原因
return new Promise((resolve, reject) => {
// 1. 同步部分:这行代码会立即执行
console.log('正在读取文件: ' + filename);
// 2. 异步部分:模拟耗时的网络请求或磁盘IO
// setTimeout 是 JS 中最典型的异步 API
// 它告诉浏览器/Node.js:"请在 1000毫秒(1秒)后把里面的代码放入任务队列"
setTimeout(() => {
// 3. 状态变更:1秒后,定时器触发
// 调用 resolve() 将 Promise 的状态从 "pending" (进行中) 变为 "fulfilled" (已成功)
// 括号里的字符串就是最终要传递给使用者的数据
resolve('文件 ' + filename + ' 读取完成');
}, 1000); // 延迟时间:1000ms
});
}
// 方式1:并行执行 (Parallel Execution)
// 这种写法下,所有任务几乎在同一时刻启动,互不等待。
console.log('\n异步并行执行:');
// --- 任务 1 ---
// 1. 立即调用 readfile_async('file1.txt'),函数内部定时器立刻开始计时 (0s -> 1s)。
// 2. .then(...) 注册了一个回调:当 file1 完成后,打印结果。
readfile_async('file1.txt').then(result => console.log(result));
// --- 任务 2 ---
// 关键点:JS 引擎不会等待上面任务 1 完成,而是立即执行这一行。
// file2 的读取操作与 file1 是同时进行的。
readfile_async('file2.txt').then(result => console.log(result));
// --- 任务 3 ---
// 同理,file3 也立即加入执行队列。
// 此时,内存中有 3 个定时器在同时倒数。
readfile_async('file3.txt').then(result => console.log(result));
// 这是最神奇的地方:变量 result 是从哪里来的?
// 源头:回顾之前的 readfile_async 函数,里面有一句 resolve('文件 file1.txt 读取完成')。
// 触发:当 1 秒钟过去,定时器触发,调用了 resolve。
// 接力:Promise 机制会自动捕获 resolve 括号里的内容。
// 注入:Promise 会立即找到你注册的 .then 函数,并把那个内容作为第一个参数塞进去。

// 03-串行执行 (Sequential Execution)
// 核心逻辑:后一个任务依赖于前一个任务的完成,或者要求严格按顺序执行。
console.log('\n异步串行执行:');
// --- 第一步:发起第一个任务 ---
readfile_async('file1.txt')
// .then() 的第一个参数是成功回调。
// 只有当 file1 读取成功后,才会进入这里。
.then(result => {
// 1. 打印 file1 的结果
console.log(result);
// 【关键点】return 一个新的 Promise!
// 这一步告诉 JS 引擎:"现在的任务还没结束,请继续等待这个新返回的 Promise 完成。"
// 这就像接力赛中,第一棒把棒子交给了第二棒。
return readfile_async('file2.txt');
})
// --- 第二步:处理第二个任务 ---
// 这里的 .then 会接收上一步 return 的那个 Promise (file2) 的结果。
.then(result => {
// 2. 打印 file2 的结果
console.log(result);
// 再次 return 一个新的 Promise,开启第三棒。
return readfile_async('file3.txt');
})
// --- 第三步:处理第三个任务 ---
.then(result => {
// 3. 打印 file3 的结果
console.log(result);
// 这里没有 return 新的 Promise,链条到此结束。
console.log('所有文件读取完成');
})
// --- 错误捕获 ---
// .catch() 就像一个安全网。
// 如果上面任何一个环节出错(比如 file2 不存在),流程会直接跳过中间的 .then,
// 直接掉进这里执行。
.catch(err => {
console.error('错误: ', err);
});

6.6 06-async-await机制.js
//// async/await 机制
// 1. 定义一个普通的函数 m()
function m() {
// 手动创建一个已经"成功"的 Promise 对象
// 相当于告诉调用者:"我虽然是个异步操作,但我现在就给你结果 'hello world'"
return Promise.resolve('hello world');
}
// 2. 调用函数并使用 .then() 获取结果
// m().then(result => console.log(result));
// 解释:调用 m() 拿到 Promise,然后注册一个回调函数。
// 当 Promise 状态变为 resolved 时,把值传给 result 并打印。

// 3. 定义一个异步函数 m_async()
async function m_async () {
// 【语法糖】直接 return 一个普通值
// 编译器会自动把它包装成 Promise.resolve('hello world')
// 效果和上面的 m() 函数完全一样,但写法更简单。
return 'hello world';
}
// 4. 定义主执行函数 main()
async function main() {
// 【核心】await 关键字
// 意思:"暂停 main 函数的执行,等待 m_async() 完成"。
// 一旦 m_async() 返回结果,就把结果赋值给 result。
// 注意:这不会阻塞整个程序,只是暂停了 main 函数内部。
const result = await m_async();
// 拿到结果后,像写同步代码一样继续往下执行
console.log(result);
}
// 5. 启动主函数
main();
// 6. 这里的代码会立即执行!
console.log('end');

async 关键字的作用
- 加在函数前面,表示这个函数是异步的。
- 它会让函数 自动返回一个 Promise 。即使你
return 123,外部拿到的也是Promise { 123 }。
await 关键字的作用
- 只能在
async函数内部使用。 - 它的作用是 "解包" 。如果
m_async()返回的是 Promise,await会帮你取出 Promise 里的值(即'hello world'),赋给变量result。 - 它让异步代码看起来像同步代码(从上到下顺序执行)