note.js速成

一、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-回调函数
  1. 使用回调函数

// 我们把 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
  • 它让异步代码看起来像同步代码(从上到下顺序执行)