Node【一】初识Node

news2024/11/25 15:00:21

文章目录

  • 🌟前言
  • 🌟Node.js
    • 🌟特性:
      • 🌟1. 单线程
      • 🌟2.异步IO
        • 🌟前端中的异步
        • 🌟Node中的异步
      • 🌟3.跨平台
      • 🌟4.运行速度快
    • 🌟 劣势:
      • 🌟 1. 不适合CPU密集型应用;
      • 🌟 2. 只支持单核CPU,不能充分利用CPU
      • 🌟 3. 可靠性低,一旦代码某个环节崩溃,整个系统都崩溃
      • 🌟 4. 开源组件库质量参差不齐,更新快,向下不兼容
  • 🌟Node.js模块系统:
      • 🌟模块化的好处:
      • 🌟Node模块分类
        • 🌟调用原生模块
        • 🌟调用文件模块
        • 🌟文件模块三种类型
      • 🌟模块的操作:
        • 🌟require 加载模块:
        • 🌟exports 创建模块:
        • 🌟module对象:
        • 🌟module的其它API:
  • 🌟Node.js包:
      • 🌟自定义包:
      • 🌟package.json
      • 🌟Package.json 属性说明
      • 🌟符合CommonJS规范的包
  • 🌟写在最后

在这里插入图片描述

🌟前言

哈喽小伙伴们,从这篇文章开始,我会开始新的专栏 Node;这个专栏里边会收录一些Node的基础知识和项目实战;今天我们开始这个专栏的第一篇文章,带领大家初识一下Node;让我们一起来看看吧🤘

🌟Node.js

Node.js是一个Javascript运行环境(runtime)。

Node.js是一个Javascript运行环境(实际上它是对Google V8引擎进行了封装)。运行在服务器端,主要用于操作服务器文件、数据库、http协议等系统底层的一些东西。

Nodej.s为了更好让Javascript运行在浏览器之外的平台,其实现了很多的模块:文件系统模块操作系统API网络通信CoreJavascript中没有或者不完善的功能。

🌟特性:

  • 单线程
  • 异步I/O /非阻塞
  • 跨平台
  • 运行速度快(依赖于Chrome V8引擎)

🌟1. 单线程

Node保持了JavaScript再浏览器中单线程的特点。

现今多数的Web 服务器中,有一条新的链接就会申请一条线程来负责处理至到这个Request 周期结束,接着执行其他流程。可以想象,成千上万个链接便有成千上万条线程(Thread-spawning )。每条线程姑且以堆栈2MB 的消耗去计算,一条条线程它们的累加都是不小的数目。如何优化和改进本身就是一个大问题,此外,使用系统线程,必须考虑线程锁的问题,否则造成堵塞主进程又是一个令人操心的难题。NodeJS 则通过基于事件的异步模型绕开了基于线程模型的所带来的问题。

NodeJS 使用JavaScript 单线程(Single-threaded )轮询事件,设计上比较简单,高并发时,不仅根本性的减少了线程创建和切换的开销(因而没有吓人的消耗),而且由于没有锁,也不会造成进程阻塞。

单线程的优点:

  • 没有死锁存在
  • 没有线程上下文交换所产生的性能开销

单线程的缺点:

  • 无法利用多核CPU
  • 错误会引起整个应用退出,应用的健壮性无法保证
  • 大量的计算占用CPU导致无法继续调用异步I/O

🌟2.异步IO

操作系统内核对于I/O只有两种方式:阻塞与非阻塞.在调用阻塞IO时,应用程序需要等待I/O完成才能返回结果.
阻塞I/O造成CPU等待I/O,浪费等待时间,CPU的处理能力不能得到充分利用.为了提高性能,内核提供了非阻塞I/O.非阻塞I/O会在调用后立即返回.

在这里插入图片描述

🌟前端中的异步

关于异步前端开发工程师非常了解,因为我们发起一个ajax请求就是一个异步调用:

console.log("执行了操作1")
$.post('/login',{user:"admin",pwd:123456},function(data){
    console.log('收到响应')
})
console.log("执行了操作2")

🌟Node中的异步

在Node中,异步I/O也很常见。以读取文件为例,我们可以看到它与前端ajax调用的方式极其类似:

在Node底层构建了很多异步I/O的API,从文件读取到网络请求等,均是如此。这样的意义在于,在Node中,我们可以从语言层面很自然的进行并行I/O操作。每个调用之间无需等待之前的I/O调用结束。在编程模型上可以极大的提高效率。

下面的两个文件读取任务的耗时取决于最慢的那个文件读取的耗时:

fs.readFile("/file1",function(err,file){
    console.log("file1读取完成")
})
fs.readFile("/file2",function(err,file){
    console.log("file2读取完成")
})

对于同步I/O而言,它们的耗时是两个任务的耗时之和。异步带来的优势是显而易见的。

🌟3.跨平台

Node.js 是跨平台的,也就是说它能运行在 Windows、OSX 和 Linux 平台上。

🌟4.运行速度快

V8是谷歌开发的,目前公认最快的 Javascript 解析引擎,libuv 是一个开源的、为 Node 定制而生的跨平台的异步 IO 库。

🌟 劣势:

🌟 1. 不适合CPU密集型应用;

CPU密集型应用给Node带来的挑战主要是:由于JavaScript单线程的原因,如果有长时间运行的计算(比如大循环),将会导致CPU时间片不能释放,使得后续I/O无法发起;
什么是cpu密集型操作(复杂的运算、图片的操作)

// 这就是一个cpu密集型的操作
for (let i = 0; i < 100000000; i++) {
    console.log(i);
}

解决方案:分解大型运算任务为多个小任务,使得运算能够适时释放,不阻塞I/O调用的发起;

🌟 2. 只支持单核CPU,不能充分利用CPU

虽然nodejs的I/O操作开启了多线程,但是所有线程都是基于node服务进程开启的,并不能充分利用cpu资源

  • pm2进程管理器可以解决这个问题
  • pm2 是一个带有负载均衡功能的Node应用的进程管理器.

🌟 3. 可靠性低,一旦代码某个环节崩溃,整个系统都崩溃

原因:单进程,单线程

解决方案:

  1. Nnigx反向代理,负载均衡,开多个进程,绑定多个端口;
  2. 开多个进程监听同一个端口,使用cluster模块;

🌟 4. 开源组件库质量参差不齐,更新快,向下不兼容

🌟Node.js模块系统:

为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。

🌟模块化的好处:

网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等…开发者不得不使用软件工程的方法,管理网页的业务逻辑。

  1. 减少文件体积
  2. 命名冲突问题
  3. 文件依赖问题
  4. 提高代码可复用性

🌟Node模块分类

NodeJS中模块分为2类:原生模块和文件模块。

模块类型描述
原生模块即Node.jsAPI提供的原生模块,原生模块在启动时已经被加载。(如:os模块、http模块、fs模块、buffer模块、path模块等)
文件模块为动态加载模块,加载文件模块的主要由原生模块module来实现和完成。原生模块在启动时已经被加载,而文件模块则需要通过调用Node.js的require方法来实现加载。

🌟调用原生模块

//调用原生模块不需要指定路径
var http = require('http');

🌟调用文件模块

//调用文件模块必须指定路径,否则会报错
var sum = require('./sum.js');

🌟文件模块三种类型

在文件模块中,又分为3类模块。这三类文件模块以后缀来区分,Node.js会根据后缀名来决定加载方法。

类型描述
.js通过fs模块同步读取js文件并编译执行。
.node通过C/C++进行编写的Addon。通过dlopen方法进行加载。
.json读取文件,调用JSON.parse解析加载。

🌟模块的操作:

在编写每个模块时,都有require、exports、module三个预先定义好的变量可供使用。

🌟require 加载模块:

require方法接受以下几种参数的传递:

  • httpfspath等,原生模块。
  • ./mod../mod,相对路径的文件模块。
  • /pathtomodule/mod,绝对路径的文件模块。
  • mod,非原生模块的文件模块。

require函数用于在当前模块中加载和使用别的模块,传入一个模块名,返回一个模块导出对象。模块名可使用相对路径(以./开头),或者是绝对路径(以/或C:之类的盘符开头)。另外,模块名中的.js扩展名可以省略。以下是一个例子。

var foo1 = require('./foo');
var foo2 = require('./foo.js');
var foo3 = require('/home/user/foo');
var foo4 = require('/home/user/foo.js');
//foo1 ~ foo4 中保存的是同一个模块的导出对象。

nodejs核心模块可以不加路径直接通过require导入:

//加载node 核心模块
var fs = require('fs');
var http = require('http');
var os = require('os');
var path = require('path');

加载和使用json文件

var data = require('./data.json');

🌟exports 创建模块:

exports对象是当前模块的导出对象,用于导出模块公有方法和属性。别的模块通过require函数使用当前模块时得到的就是当前模块的exports对象。以下例子中导出了一个公有方法。

//sum.js
exports.sum = function(a,b){
    return a+b;
}

//main.js
var m = require("./sum");
var num = m.sum(10,20);
console.log(num);

🌟module对象:

通过module对象可以访问到当前模块的一些相关信息,但最多的用途是替换当前模块导出对象。例如模块默认导出对象默认是一个普通对象,如果想改为一个函数可以通过如下方式:

导出一个普通函数:

//sum.js
function sum(a,b){
    return a+b;
}
module.exports= sum;
//main.js
var sum = require('./sum');
sum(10,20);// 30

导出一个构造函数:

//hello.js
function hello(){
    this.name ="你的名字";
    this.setName = function(name){
        this.name = name;
    }
    this.sayName = function(){
        alert(this.name);
    }
}
module.exports= hello;

//main.js
var hello = require('./hello.js');
var o = new hello();
o.setName('张三');
o.sayName(); // 张三

🌟module的其它API:

每一个js文件都是一个模块,每一个模块都有一个对象这个对象的可以通过module访问到,该对象上保存了一些我们当前模块的状态:

API描述
module.id模块的ID,通常是当前模块文件路径,含文件名
module.filename当前模块文件路径,含文件名
module.loaded判断模块当前是否已加载
module.parent加载当前脚本的模块对象。
module.children当前模块加载的模块对象集合,是一个数组

🌟Node.js包:

由多个子模块组成的大模块称作包。

🌟自定义包:

在组成一个包的所有子模块中,需要有一个入口模块,入口模块的导出对象被作为包的导出对象。例如有以下目录结构。

d:/node/calc/
/calc
    sum.js            //加法
    subtraction.js    //减法
    multiplication.js //乘法
    division.js       //除法
    main.js           //主模块 入口模块

calc目录定义了一个包,其中包含了4个子模块,main.js作为入口模块。

var sum = require('./sum.js');
var subtraction = reuqire('./subtraction.js');
var multiplication = require('./multiplication.js');
var division = require('./division.js');

function calc(a,tag,b){
    switch(tag){
        case '+':
        return sum(a,b);
        break;
        case '-':
        return subtraction(a,b);
        break;
        case '*':
        return multiplication(a,b);
        break;
        case '/':
        return division(a,b);
    }
}
module.exports = calc;

然后我们要使用这个包

//d:/node/use.js

var calc = require('./calc/main.js');
console.log(clac(10,'+',100));

但是这样使用感觉不像一个包。

var calc = require('./calc');

🌟package.json

如果想自定义入口模块的文件名和存放位置,就需要在包目录下包含一个 package.json 文件,package.json是包的配置文件。

d:/node/calc/
/calc
    sum.js            //加法
    subtraction.js    //减法
    multiplication.js //乘法
    division.js       //除法
    main.js           //主模块 入口模块

//package.json
{
    "name": "calc",
    "main": "./calc/main.js"
}

🌟Package.json 属性说明

属性描述
name包名。
version包的版本号。
description包的描述。
homepage包的官网 url 。
author包的作者姓名。
contributors包的其他贡献者姓名。
devDependencies开发环境依赖包列表。
dependencies生产环境依赖包列表。如果依赖包没有安装,npm 会自动将依赖包安装在 node_module 目录下。
repository包代码存放的地方的类型,可以是 git 或 svn,git 可在 Github 上。
mainmain 字段是一个模块ID,它是一个指向你程序的主要项目。就是说,如果你包的名字叫 express,然后用户安装它,然后require(“express”)。
keywords关键字
它是这样一个json文件(注意:json文件内是不能写注释的,复制下列内容请删除注释):

{
  "name": "test",                                      //项目名称(必须)
  "version": "1.0.0",                                  //项目版本(必须)
  "description": "This is for study gulp project !",   //项目描述(必须)
  "homepage": "",                                      //项目主页
  "repository": {                                      //项目资源库
    "type": "git",
    "url": "https://git.oschina.net/xxxx"
  },
  "author": {                                          //项目作者信息
    "name": "surging",
    "email": "surging2@qq.com"
  },
  "license": "ISC",                                    //项目许可协议
  "devDependencies": {                                 //项目开发依赖包
    "gulp": "^3.8.11",
    "gulp-less": "^3.0.0"
  },
  dependencies:{                                       //项目生产依赖包

  }
}

🌟符合CommonJS规范的包

包是在模块基础上更深一步的抽象,Nodejs 的包类似于 C/C++ 的函数库或者 Java/.Net 的类库。它将某个独立的功能封装起来,用于发布、更新、依赖管理和版本控制。Nodejs 根 据 CommonJS 规范实现了包机制,开发了 npm来解决包的发布和获取需求。

Node.js 的包是一个目录,其中包含一个 JSON 格式的包说明文件 package.json。严格符 合 CommonJS 规范的包应该具备以下特征:

文件类型描述
package.json必须在包的顶层目录下
二进制文件应该在 bin 目录下
JavaScript应该在 lib 目录下
文档应该在 doc 目录下
单元测试应该在 test 目录下

Node.js 对包的要求并没有这么严格,只要顶层目录下有 package.json,并符合一些规范即可。当然为了提高兼容性,我们还是建议你在制作包的时候,严格遵守 CommonJS 规范。

/
 ├── bin/            # 存放命令行相关代码
 │
 ├── src/            # 开发目录
 │
 ├── doc/            # 存放文档
 │
 ├── lib/            # 存放API相关代码
 │
 ├── node_modules/   # 存放三方包
 │
 ├── tests/          # 存放测试用例
 │
 ├── package.json    # 元数据文件
 │
 └── README.md        # 说明文件

🌟写在最后

这篇文章开启了我们的Node专栏,更多组Node知识以及API请大家持续关注,尽请期待。各位小伙伴让我们 let’s be prepared at all times!

✨原创不易,还希望各位大佬支持一下!
👍 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/417618.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ASP一个物流商品运输系统的设计与实现

物流运输行业的今天正朝着追求高效、低成本、稳定可靠的方向发展。本文详细介绍了网上物流管理系统&#xff0c;涉及到客户端运输线路设计、过程跟踪等功能模块以及管理员端的相应模块的具体实现&#xff0c;分析了整个系统的架构、工作原理、实现功能等。系统采用ASPMS SQL以B…

代码随想录算法训练营第43天 | 动态规划 背包理论基础 LeetCode1049.最后一块石头的重量II,494.目标和,474.一和零

代码随想录算法训练营第43天 | 动态规划 背包理论基础 LeetCode1049.最后一块石头的重量II&#xff0c;494.目标和&#xff0c;474.一和零 1049.最后一块石头的重量II 第一遍读题思考 重点在于背包问题的理论基础建议阅读以下两个链接。 背包问题理论基础&#xff0c;用二维…

sed命令基础

sed编辑器即流编辑器&#xff08;stream editor&#xff09;&#xff0c;根据命令处理数据流中的数据&#xff0c;这些命令可从命令行输入&#xff0c;或者指定文件中输入。 sed执行的操作如下&#xff1a; 1&#xff09;从输入读取一行数据 2&#xff09;根据提供的命令匹配数…

KSS-ICP: 基于形状分析技术的点云配准方法

目录 1. 概述 2. 算法实现 3. 实验结果 总结 Reference 三维点云配准是三维视觉领域一个经典问题&#xff0c;涉及三维重建&#xff0c;定位&#xff0c;SLAM等具体应用问题。传统的配准可以被分为两条技术路线&#xff0c;即基于全局姿态匹配的方法以及基于特征点对应的方法。…

疫情下社区管理系统的设计与实现(论文+源码)_kaic

疫情下社区管理系统 摘 要&#xff1a;新冠疫情下的社区人员管理系统是基于SpringBoot搭建的一套前后端分离系统。面向疫情下的社区管理人员和社区用户&#xff0c;主要用于进行社区服务&#xff0c;进行高效的社区人员管理。具有一定的经济效益和社会效益。本文分析了新冠疫情…

计算机网络第三章(数据链路层)【湖科大教书匠】

1. 概述 物理层发出去的信号需要通过数据链路层才知道是否到达目的地&#xff1b;才知道比特流的分界线 链路(Link)&#xff1a;从一个结点到相邻结点的一段物理线路&#xff0c;中间没有任何其他交换结点数据链路(Data Link)&#xff1a;把实现通信协议的硬件和软件加到链路…

【ROS实操2话题订阅输出乌龟位姿】

需求描述 已知turtlesim中的乌龟显示节点&#xff0c;会发布当前乌龟的位姿(窗体中乌龟的坐标以及朝向)&#xff0c;要求控制乌龟运动&#xff0c;并时时打印当前乌龟的位姿。 实现分析 1.首先&#xff0c;需要启动乌龟显示以及运动控制节点并控制乌龟运动。 2.要通过ROS命令…

网络原理TCP协议

hi,我们又见面了,今天为大家带来TCP协议,一共为大家介绍TCP协议的十个核心特性 1.确认应答 2.超时重传 3连接管理 4滑动窗口 5流量控制 6拥塞控制 7延迟应答 8捎带应答 9面向字节流(粘包问题) 10异常情况(心跳包) 11基于TCP应用层协议 TCP协议位于传输层,我们知道T…

微信小程序开发 | API应用案例(上)

API应用案例&#xff08;上&#xff09;5.1【案例1】用户登录5.1.1 案例分析5.1.2 前导知识5.1.3 搭建开发者服务器5.1.4 实现用户登录5.1.5 检查用户是否已经登录5.1.6 获取用户信息5.1.7 开放数据校验与解密5.2【案例2】个人中心5.2.1 案例分析5.2.2 前导知识5.2.3 实现底部标…

BE-SSL:基于边界增强自监督学习的脑结构分割

文章目录Boundary-Enhanced Self-supervised Learning for Brain Structure Segmentation摘要本文方法Supervoxel BranchRegistration BranchAtlas Selection实验结果Boundary-Enhanced Self-supervised Learning for Brain Structure Segmentation 摘要 边界增强自监督学习(…

用Pytorch搭建一个房价预测模型

本文参加新星计划人工智能(Pytorch)赛道&#xff1a;https://bbs.csdn.net/topics/613989052 目录 一、项目介绍 二、准备工作 三、实验过程 3.1数据预处理 3.2拆分数据集 3.3构建PyTorch模型 3.3.1.数据转换 3.3.2定义模型架构 3.3.3定义损失准则和优化器 3.3.4创建…

Linux查看端口

目录 1.查看已知端口的使用情况 2.查看所有端口的占用情况 3.查看占用端口的程序的进程号 4.杀死进程号 1.查看已知端口的使用情况 #例:8080 可使用命令: netstat -anp | grep 8080 结果如下: 还可以使用这条命令: netstat -tln | grep 8080 结果如下: 区别:第一条命令后面显示…

评分卡模型(二)基于评分卡模型的用户付费预测

评分卡模型&#xff08;二&#xff09;基于评分卡模型的用户付费预测 小P&#xff1a;小H&#xff0c;这个评分卡是个好东西啊&#xff0c;那我这想要预测付费用户&#xff0c;能用它吗 小H&#xff1a;尽管用&#xff5e; &#xff08;本想继续薅流失预测的&#xff0c;但想了…

DevExpress WinForms电子表格控件,更快拥有现代办公体验!(二)

DevExpress WinForm Spreadsheet组件能读写XLSx、XLS、CSV、TXT文件、打印并导出为PDF等&#xff0c;为终端用户提供了当今流行的办公UI体验&#xff01;在上文中&#xff08;点击这里回顾>>&#xff09;&#xff0c;我们介绍了DevExpress WinForm中Excel启发式的电子表格…

【计算机网络-数据链路层】集线器、网桥、交换机

本文许多文字和图片使用了湖科大教书匠&#xff08;高军老师&#xff09;的 PPT&#xff0c;在此表示感谢。正是他让非科班的我能以奇妙的方式走进网络的世界。 文章目录1 【物理层】集线器&#xff08;Hub&#xff09;——共享式以太网1.1 为什么使用集线器&#xff1f;1.2 集…

救命,我好像发现了测试工程师面试通关秘籍

一、自我介绍 &#xff08;自我介绍不局限于下面模板&#xff0c;灵活表达&#xff09; 面试官你好&#xff0c;我叫xxx&#xff0c;今年xx岁&#xff0c;家乡是xx省xx市。20xx年毕业后一直从事软件测试工作&#xff0c;到现在已经x年了。 目前为止&#xff0c;经历过x家公司…

基于SpringBoot的大学生体质测试管理系统源码数据库论文

目录 目录 1 绪 论 1.1系统背景介绍 1.2课题研究的目的和意义 1.3系统的研究现状 1.4系统实现的功能 1.5系统的特点 2 开发工具和技术 2.1 B/S体系结构 2.2 Java语言简介 2.3 SpringBoot框架 2.4 MySQL简介 3 系统需求分析 3.1 系统可行性分析及目的…

JS数组reduce()方法详解及高级技巧

reduce()方法可以搞定的东西&#xff0c;for循环&#xff0c;或者forEach方法有时候也可以搞定&#xff0c;那为啥要用reduce()&#xff1f;这个问题&#xff0c;之前我也想过&#xff0c;要说原因还真找不到&#xff0c;唯一能找到的是&#xff1a;通往成功的道路有很多&#…

QtableWidget插入数据卡顿优化方法

最近要使用Qtablewidget保存4300多的数据&#xff0c;发现以下刷新4300条数据&#xff0c;界面会变得非常卡顿&#xff0c;于是想了优化一下&#xff1b;因为要对所有数据排序&#xff0c;想用一下Qtablewidget自动排序功能&#xff0c;而且数据量不多&#xff0c;不想采用动态…

【教学类-32-02】十二生肖2.0版(绘画+手工+排序+左右分类+玩牌)(中班:偏科学-数)

作品展示 2.0样式——动物头部方向随机向左、或者向右 背景需求 1.0样式——动物头部方向全部向右&#xff0c; 我希望孩子分类的时候还能够“判断生肖头部的方向做一个左右分类” 素材准备&#xff1a; 1、图片准备 office PPT2013里面有一个图标的功能&#xff0c;内置大量…