nodejs初步学习

什么是nodejs?

  • Node.js 就是运行在服务端的 JavaScript。
  • Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
  • Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

nodejs的特性?

单线程


我们都知道Node.js的runtime是v8,v8在设计之初是Chrome使用在浏览器对JavaScript语言的解析运行引擎,其最大的特点是单线程,而在Node.js对v8的沿用也是针对这一非常重要的特点。什么是单线程?简单来说就是一个进程中只有一个线程,程序顺序执行,前面执行完成才会执行后面的程序。来看个Node.js对http服务的模型:
这里写图片描述
Node.js的单线程指的是主线程是“单线程”,由主要线程去按照编码顺序一步步执行程序代码,假如遇到同步代码阻塞,主线程被占用,后续的程序代码执行就会被卡住。实践一个测试代码

var http = require('http');

function sleep(time) {
    var _exit = Date.now() + time * 1000;
    while( Date.now() < _exit ) {}
    return ;
}

var server = http.createServer(function(req, res){
    sleep(10);
    res.end('server sleep 10s');
});

server.listen(8080);

下面为代码块的堆栈图:
这里写图片描述
JavaScript是解析性语言,代码按照编码顺序一行一行被压进stack里面执行,执行完成后移除然后继续压下一行代码块进去执行。上面代码块的堆栈图,当主线程接受了request后,程序被压进同步执行的sleep执行块(我们假设这里就是程序的业务处理),如果在这10s内有第二个request进来就会被压进stack里面等待10s执行完成后再进一步处理下一个请求,后面的请求都会被挂起等待前面的同步执行完成后再执行,所以这也说明Node.js单线程的执行模型,因为这样的特性,我们的页面不能有耗时很长的同步处理程序阻塞了程序的后续执行,而对于耗时过长的程序应该采用异步执行,这里也就是Node.js的第二个特性,异步。

异步


我们平时都会说Node.js是异步,但是所说的异步具体指的是什么异步?更进一步的说应该是主线程的异步处理函数队列+多线程异步I/O。
主线程的异步处理函数队列

首先,所谓的主线程的异步处理函数队列指的是主线程的主要执行空间除了stack以及heap外,还有callback queue(回调函数队列),而callback queue是存放了异步处理的回调函数,在一个执行块里面,当里面的同步代码执行完成后,会从callback queue里面取出回调函数一个个执行,我们最常见的异步处理函数就是setTimeout,一个简单的例子来讲述:

function sleep(time) {
    var _exit = Date.now() + time * 1000;
    while( Date.now() < _exit ) {}
    return ;
}

function main(){
    setTimeout(function(){
        console.log('setTimeout run');
    },0);
    sleep(5);
    console.log('after sleep');
}

main();

/** 执行输出
    after sleep
    setTimeout run
**/

下面是代码块的主线程堆栈执行:
这里写图片描述
看上图,主线程将main函数压进stack里面一行行解析执行,首先遇到setTimeout方法,因为setTimeout是一个异步处理函数,这里会把setTimeout(callback,timeout),里面的callback函数移进callback queue里面,同时会把自己从主线程的stack里面移除,继续压进后面的执行代码来解析执行,这里继续压进sleep沉睡5s,接下来执行console,等到这里的同步代码执行完成后这个时候就会从callback queue(FIFO顺序)里面取回调函数一个个执行。(题外话:就算setTimeout里面的timeout设置了是0,都是要等待执行块里面的同步代码执行完成后再去执行callback queue里面的代码)这就是异步里面的其一:主线程异步函数处理队列。

多线程异步I/O

一看标题多线程异步I/O可能会有疑问,不是说Node.js是单线程的吗?其实这里并没有冲突,Node.js每个进程里面只有一个主线程来处理程序,所以,主线程是单线程的。而主线程之外调用的I/O处理是通过一个叫做线程池来管理和分配线程来处理I/O,所以对I/O的处理是多线程。而主线程和I/O线程池则通过上面刚刚讲述的主线程的异步处理函数队列来协作。除了上文所说的timers模块里面的setTimeout函数外,Node.js还对文件系统、网络都实现了异步化调用(题外话:系统底层的I/O异步化都是基于c++的异步框架libuv来实现,然后往上层提供JavaScript调用接口)此处之前理解有误,应该是Node.js只对文件系统以及DNS实现了多线程I/O封装,网络I/O还是采用单线程形式(可参考libuv设计概述原文:Important libuv uses a thread pool to make asynchronous file I/O operations possible, but network I/O is always performed in a single thread, each loop’s thread.感谢bd_bai指正)
这里写图片描述
而Node.js的高性能也是得益于其将阻塞的I/O异步化,使得不影响主逻辑的执行。

事件驱动


文章至此,先简单总结一下Node.js的两个简单特性,每个Node.js进程只有一个主线程在执行程序代码,在执行的过程中Node.js将阻塞的I/O异步化,并将其回调函数插入callback queue里面,等待同步逻辑执行完成后再通过callback queue里面取出回调函数压进stack里面执行。好了,而事件驱动的作用就是取出回调函数。事件驱动又叫事件循环,是指主线程从主线程的异步处理函数队列里面不停循环的读取事件,驱动了所有的异步回调函数的执行。

这里写图片描述
至此整个Node.js的异步化逻辑可以不断循环的跑起来了,以上则是我们日常所言的Node.js的三大特性以及其原理

为什么要使用nodejs?

总的来说,Node.js 适合以下场景:

  1. 实时性应用,比如在线多人协作工具,网页聊天应用等。
  2. 以 I/O 为主的高并发应用,比如为客户端提供 API,读取数据库。
  3. 流式应用,比如客户端经常上传文件。
  4. 前后端分离。

实际上前两者可以归结为一种,即客户端广泛使用长连接,虽然并发数较高,但其中大部分是空闲连接。

Node.js 也有它的局限性,它并不适合 CPU 密集型的任务,比如人工智能方面的计算,视频、图片的处理等

nodejs的优缺点?

Node.js优点:
1、采用事件驱动、异步编程,为网络服务而设计。其实Javascript的匿名函数和闭包特性非常适合事件驱动、异步编程。而且JavaScript也简单易学,很多前端设计人员可以很快上手做后端设计。
2、Node.js非阻塞模式的IO处理给Node.js带来在相对低系统资源耗用下的高性能与出众的负载能力,非常适合用作依赖其它IO资源的中间层服务。
3、Node.js轻量高效,可以认为是数据密集型分布式部署环境下的实时应用系统的完美解决方案。Node非常适合如下情况:在响应客户端之前,您预计可能有很高的流量,但所需的服务器端逻辑和处理不一定很多。
Node.js缺点:
1、可靠性低
2、单进程,单线程,只支持单核CPU,不能充分的利用多核CPU服务器。一旦这个进程崩掉,那么整个web服务就崩掉了。
不过以上缺点可以可以通过代码的健壮性来弥补。
目前Node.js的网络服务器有以下几种支持多进程的方式:
1 开启多个进程,每个进程绑定不同的端口,用反向代理服务器如 Nginx 做负载均衡,好处是我们可以借助强大的 Nginx 做一些过滤检查之类的操作,同时能够实现比较好的均衡策略,但坏处也是显而易见——我们引入了一个间接层。
2 多进程绑定在同一个端口侦听。在Node.js中,提供了进程间发送“文件句柄” 的功能,这个功能实在是太有用了(貌似是yahoo 的工程师提交的一个patch) ,不明真相的群众可以看这里: Unix socket magic
3 一个进程负责监听、接收连接,然后把接收到的连接平均发送到子进程中去处理。
在Node.js v0.5.10+ 中,内置了cluster 库,官方宣称直接支持多进程运行方式。Node.js 官方为了让API 接口傻瓜化,用了一些比较tricky的方法,代码也比较绕。这种多进程的方式,不可避免的要牵涉到进程通信、进程管理之类的东西。此外,有两个Node.js的module:multi-node 和 cluster ,采用的策略和以上介绍的类似,但使用这些module往往有一些缺点:
1 更新不及时
2 复杂庞大,往往绑定了很多其他的功能,用户往往被绑架#3 遇到问题难以解决

<think>好的,用户让我介绍一下Node.js的常见知识,我需要整理一个清晰的结构,确保涵盖主要方面。首先,我应该从Node.js的基本定义开始,解释它是什么,它的核心特点,比如基于Chrome V8引擎、事件驱动、非阻塞I/O模型。这样用户能有一个初步的理解。 接下来,需要讨论Node.js的适用场景,比如高并发、I/O密集型应用,还有它不太适合CPU密集型任务。这部分需要对比传统服务端语言,比如PHP或Java,说明Node.js的优势和劣势,这样用户能知道何时选择它。 然后,模块系统是Node.js的重要组成部分,应该介绍CommonJS模块化,如何用require和module.exports来导入导出模块,以及ES6模块的支持情况。可能还要提到内置的核心模块,如fs、http、path等,以及npm的作用,这样用户了解模块化管理的方法。 异步编程是关键部分,需要详细说明回调函数、Promise、async/await,以及事件循环机制。这里要强调回调地狱的问题,以及如何用Promise和async/await来优化代码结构。同时,事件循环的几个阶段需要简单解释,帮助用户理解异步执行的原理。 常用框架和工具也是用户关心的,Express和Koa作为Web框架,Nest.js的现代化特性,Socket.IO处理实时通信,PM2用于进程管理,这些都是常用的工具,应该列举并简要说明它们的作用。 调试和性能优化方面,内置调试器、Chrome DevTools、以及常用的性能分析工具如clinic.js和node-inspector需要提到。性能优化策略如避免阻塞操作、使用集群、缓存等,都是实际开发中需要注意的点。 最后,要提到学习资源,官方文档、npm官网、Stack Overflow、中文社区如CNode,帮助用户进一步自学。可能还要补充一些常见问题,比如单线程的限制,如何处理CPU密集型任务,错误处理的最佳实践,安全注意事项,版本管理的重要性等。 在整理这些内容时,要注意语言简洁,结构清晰,避免使用过于专业的术语,或者必要时给出解释。同时,结合用户可能的实际需求,比如开发Web应用、API服务,或者工具脚本,来举例说明Node.js的应用场景,这样用户更容易理解。需要检查是否有遗漏的重要知识点,比如事件循环的各个阶段,或者最新的ES模块支持情况,确保信息的准确性和时效性。可能还需要提醒用户注意版本差异,比如Node.js的LTS版本和当前版本的区别,以及npm包的安装和管理技巧。总之,目标是提供一个全面而易于理解的Node.js介绍,帮助用户快速掌握核心概念和常见用法。Node</think>.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,专为高性能、高并发的服务器端应用设计。以下是其核心知识点和常见应用场景的整理: --- ### **一、核心特点** 1. **非阻塞 I/O (异步模型)** - 通过事件循环(Event Loop)处理并发请求,避免线程阻塞。 - 适合 I/O 密集型场景(如文件读写、网络请求)。 2. **单线程与事件驱动** - 主线程处理事件回调,通过异步操作实现高并发。 - CPU 密集型任务可能成为性能瓶颈(需用子进程或 Worker Threads 优化)。 3. **模块化系统** - 基于 CommonJS 规范,使用 `require()` 和 `module.exports` 管理模块。 - 支持 ES6 模块(需 `.mjs` 扩展名或 `package.json` 配置)。 4. **NPM 生态** - 全球最大的开源库生态系统(如 `express`、`lodash`、`axios` 等)。 - 通过 `npm install` 管理依赖。 --- ### **二、适用场景** 1. **API 服务** - 快速构建 RESTful API(常用框架:Express、Koa、Fastify)。 2. **实时应用** - 聊天应用、在线协作工具(结合 WebSocket,如 `socket.io`)。 3. **微服务架构** - 轻量级、低资源消耗,适合容器化部署(如 Docker + Kubernetes)。 4. **工具链开发** - 构建工具(Webpack、Babel)、脚本工具等。 --- ### **三、核心模块** 1. **内置模块** - `fs`:文件系统操作。 - `http`/`https`:创建 HTTP 服务器。 - `path`:处理文件路径。 - `events`:事件触发器(如 `EventEmitter`)。 - `child_process`:创建子进程。 2. **常用第三方库** - `Express`:轻量级 Web 框架。 - `Sequelize`/`Mongoose`:数据库 ORM/ODM。 - `Axios`:HTTP 客户端。 - `PM2`:进程管理工具(日志、集群、热更新)。 --- ### **四、异步编程模式** 1. **回调函数(Callback)** - 基础异步模式,但易导致“回调地狱”。 ```javascript fs.readFile('file.txt', (err, data) => { if (err) throw err; console.log(data); }); ``` 2. **Promise** - 链式调用解决回调嵌套问题。 ```javascript fs.promises.readFile('file.txt') .then(data => console.log(data)) .catch(err => console.error(err)); ``` 3. **Async/Await** - 以同步写法处理异步操作(需配合 `try/catch`)。 ```javascript async function readFile() { try { const data = await fs.promises.readFile('file.txt'); console.log(data); } catch (err) { console.error(err); } } ``` --- ### **五、性能优化技巧** 1. **避免阻塞主线程** - 将 CPU 密集型任务交给子进程或 Worker Threads。 2. **使用集群模式** - 利用多核 CPU(如 `cluster` 模块或 PM2 集群)。 3. **缓存机制** - 使用 Redis 或内存缓存减少重复计算。 4. **代码优化** - 避免同步方法(如 `fs.readFileSync`)。 - 使用流(Stream)处理大文件。 --- ### **六、常见问题** 1. **如何处理 CPU 密集型任务?** - 使用 `worker_threads` 模块或拆分为独立微服务。 2. **如何调试 Node.js 应用?** - 内置调试器(`node inspect`)、Chrome DevTools 或 VS Code 调试插件。 3. **如何保证应用稳定性?** - 使用 PM2 守护进程、配置日志轮转、监控内存泄漏。 --- ### **七、学习资源** - **官方文档**:[nodejs.org](https://nodejs.org/) - **中文社区**:[CNode](https://cnodejs.org/) - **在线课程**:Udemy、慕课网的 Node.js 实战教程。 --- 掌握这些核心知识后,可结合具体项目实践(如搭建 API 服务、开发 CLI 工具)深化理解。遇到问题时,善用 NPM 生态和社区资源是关键!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值