Node.js

2021/4/19 20:28:20

本文主要是介绍Node.js,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Node

  • 命令行窗口
    • 常用的指令
    • 目录
    • 环境标量(windows系统中的变量)
  • 进程和线程
    • 进程
    • 线程
      • 单线程
      • 多线程
  • Node.js简介
  • Node的用途
  • Node
  • COMMONJS规范
    • ECMAScript标准的缺点
    • CommonJS规范
  • 模块化简介
    • Node模块化详解
      • 引入模块
      • 全局对象global
  • 包简介
    • package
  • npm
    • npm简介
    • npm命令
    • 引入包
    • cnpm
    • Buffer缓冲区
    • fs(文件系统)
      • 同步和异步调用
      • 同步文件的写入
      • 异步文件的写入
      • 简单文件写入
      • 流式文件写入
      • 简单文件读取
      • 流式文件读取
      • fs模块的其他方法

命令行窗口

  • 又名:小黑屏、CMD窗口、终端、shell、DOS窗口
  • 如何打开:-开始菜单–>运行–>CMD–>回车

常用的指令

  • dir:列出当前目录下的所有文件
  • cd 目录名:进入到指定的目录
  • md 目录名:创建一个文件夹
  • rd 目录名:删除一个文件夹
  • 直接输入文件名:打开文件

目录

  • .表示当前目录
  • ..表示上一级目录

环境标量(windows系统中的变量)

  • path
    • 当我们在命令行窗口打开一个文件,或调用一个程序时,
    • 系统会首先在当前目录下寻找文件程序,如果找到了则直接打开,
    • 如果没有找到会依次到环境变量path的路径中寻找,知道找到为止,
    • 如果没有找到则报错。
  • 所以我们可以将一些经常需要访问的程序和文件的路径添加到path中,这样我们就可以在任意位置来访问这些文件和程序了。
  • 如何打开:计算机右键–>高级系统设置–>环境变量

进程和线程

进程

  • 负责为程序的运行提供必备的环境
  • 进程就相当于工厂中的车间

线程

  • 计算机中的最小的计算单位,线程负责执行进程中的程序
  • 线程就相当于工厂的工人

单线程

  • JS是单线程的

多线程


Node.js简介

  • node.js是一个能够在服务器端运行的javascript的开放源代码、跨平台javascript运行环境。
  • node采用google开发的v8引擎运行js代码,使用事件驱动、非阻塞和异步I/O模型等技术来提高性能,可优化应用程序的传输量和规模。
  • node大部分基本模块都用javascript编写。在node出现之前,js通常作为客户端程序设计语言使用,以js写出的程序常在用户的浏览器上运行。

Node的用途

  • Web服务API,比如rest
  • 实时多人游戏
  • 后端的web服务,例如跨域、服务器端的请求
  • 基于web的应用
  • 多客户端的通信,如即时通信

Node

  • node是es标准一个实现,node也是一个js引擎
  • 通过node可以使js代码在服务器端执行
  • node仅仅对es标准进行了实现,所以在node中不包含dom和bom
  • node中可以使用所有的内建对象
    • String Number Boolean Math Date RegExp Function object Array
    • 而bom和dom都不能使用
    • 但是可以使用console,也可以使用定时器(setTimeout()setInertval()
  • node可以在后台来编写服务器
    • 进程:进程就是一个一个工作计划(工厂中的车间)
    • 线程:线程是计算机的最小运行单位(工厂中的工人,是干活的)
  • 传统的服务器都是多线程的,每进来一个请求,就创建一个线程去处理请求
  • node的服务器是单线程的,但是在后台拥有一个i/o线程池

COMMONJS规范

ECMAScript标准的缺点

  • 没有模块系统
  • 标准库较少
  • 没有标准接口
  • 缺乏管理系统

CommonJS规范

  • ComminJS规范的提出,主要是为了弥补当前javascript没有标准的缺陷。
  • CommonJS规范为JS指定了一个美好的愿景,希望JS能够在任何地方运行。
  • CommonJS对模块化的定义十分简单:模块引用、模块定义、模块标识

模块化简介

  • 如果程序设计的规模达到了一定程度,则必须对其进行模块化。
  • 模块化可以有多种形式,但至少应该提供能够将代码分割为多个源文件的机制。
  • CommonJS的模块化功能可以帮我们解决该问题。

Node模块化详解

  • 在node中,一个js文件就是一个模块
  • 在node中,每一个js文件中的js代码都是独立运行在一个函数中,而不是全局作用域,所以一个模块中的变量和函数在其他模块中无法访问。
  • 我们可以通过exports来向外部暴露变量和方法,只需要将需要暴露给外部的变量或函数设置为exports的属性即可

引入模块

  • 在node中,通过require()函数来引入外部的模块
  • require()可以传递一个文件的路径作为参数,node将会自动根据该路径来引入外部模块,如果是相对路径,必须以./../开头
  • 使用require()引入模块后,该函数会返回一个对象,这个对象代表的是引入的模块
  • 示例:var md = require("./module.js")
  • 我们使用require()引入外部模块时,使用的就是模块标识,我们可以通过模块表示来找到指定的模块
  • 模块分为两大类
    • 核心模块
      • 由node引擎提供的模块
      • 核心模块的标识就是模块的名字
    • 文件模块
      • 由用户自己创建的模块
      • 文件模块的标识就是文件的路径(绝对路径,相对路径)

全局对象global

  • 在node中有一个全局对象global,他的作用和网页中的window类似
    • 在全局中创建的变量都会作为global的属性保存
    • 在全局中创建的函数都会作为global的方法保存
  • 当node在执行模块中的代码时,它会首先在代码外部添加函数,将代码嵌套进去,实际上模块中的代码都是包装在一个函数中执行,并且在函数执行时,同事传递进了5个实参
    • function (exports, require, module, __filename, __dirname) {}
    • exports:该对象用来将变量或函数暴露在外部
    • require:函数,用来引入外部的模块
    • module:module代表的是当前模块本身,exports就是module的属性
      • exports和module.exports:
        • 通过exports只能使用.的方式来向外暴露内部变量
        exports.xxx = xxx
        
        • 而module.exports既可以通过.的形式,也可以直接赋值
         module.exports.xxx = xxx;
         module.exports = {}
        
    • __filename:当前模块的完整路径
    • __dirname:当前模块所在的文件夹路径

包简介

package

  • Commonjs的包规范允许我们将一组相关的模块组合到一起,形成一组完整的工具。
  • CommonJS的包规范由包结构包描述文件两个部分组成
  • 包结构:包实际就是一个压缩文件,解压以后还原为目录。符合规范的目录,应该包含如下文件:
    • package.json:包描述文件,包描述文件用于表达非代码相关的信息,它是一个JSON格式的文件,位于包的根目录下,是包的重要组成部分。package.json文件中的字段:
      • name:名字
      • description:描述
      • version:版本
      • keywords:关键字,用于搜索
      • maintainers:主要贡献者
      • contributors:维护者
      • bugs:提交bug的地址
      • licenses:协议、版权
      • repositories:仓库,git或者svn的地址
      • dependencies:包的相关依赖
      • homepage:包的主页
      • os:系统
      • cpu:cpu
      • engine:引擎
      • builtin:构建工具
      • directories:来制定一些方法来描述模块的结构
      • implements
      • scripts:指定了项目的生命周期个各个环节需要执行的命令
      • author
      • bin
      • main:包的主入口文件
      • devSependencies:开发的依赖
    • bin:可执行二进制文件
    • lib:JS代码
    • doc:文档
    • test:测试单元

npm

npm简介

  • 全称:Node Package Manager
  • CommonJS包规范是理论,npm是其中一种实践
  • 对于node而言,npm帮助其完成了第三方模块的发布、安装和依赖等。借助npm,node与第三方模块之间形成了很好的一个生态系统

npm命令

  • npm -v:查看版本
  • npm version:查看所有模块的版本
  • npm:帮助说明
  • npm search 包名:搜索相关包
  • npm install 包名 / npm i 包名:安装包
  • npm init:初始化
  • npm remove 包名 / npm r 包名:删除包
  • npm install 包名 --save / npm i 包名 --s:安装包并添加到依赖中
  • npm install:安装项目所依赖的包
  • npm install 包名 -g:全局安装包(全局安装的包一般都是一些工具)

引入包

  • 通过npm下载的包都会方法哦node_modules文件夹中
  • 我们通过npn下载的包,直接通过报名引入即可
  • node在使用模块名字引入模块时,它会首先在当前目录的node_modules中寻找是否含有该模块,如果有则直接使用,如果没有则去上一级目录的node_modules中寻找,直到找到为止,直到找到磁盘的根目录,如果依然没有,则报错

cnpm

  • 配置cnpm:npm install -g cnpm --registry=https://registry.npm.taobao.org

Buffer缓冲区

  • Buffer的结构和数组很像,它的元素为16进制的两位数,操作的方法也和数组类似。
  • 实际上一个元素就表示内存中的一个字节。
  • 实际上Buffer中的内存不是通过javascript分配的,而是在底层通过c++申请的。
  • 也就是我们可以直接通过buffer来创建内存中的空间。
  • 数组中不能存储二进制的文件,而Buffer就是专门用来存储二进制数据的。
  • 在buffer中存储的都是二进制数据,但是在显示时都是16进制的形式显示。
  • buffer中的每一个元素的范围是从00-ff
  • 使用buffer不需要引入模块,直接使用即可
  • 示例:将一个字符串保存到buffer中
    var str = "hello world";
    // 将一个字符串保存到buffer中
    var buf = Buffer.from(str);
    console.log(buf)  // <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>
    
  • Buffer的使用方法:
    • Buffer.from(str):将一个字符串转换为buffer
    • Buffer.alloc(size):创建一个指定大小的buffer
    • Buffer.allUnsafe(size):创建一个指定大小的buffer,但是可能包含敏感数据
    • Buffer.toString():将缓冲区中的数据转换为字符串

fs(文件系统)

  • 全称:File System
  • 文件系统简单来说就是通过node来操作系统中的文件。
  • 在node中,与文件系统的交互是非常重要的,服务器的本质就将本地的文件发送给远程的客户端。
  • node通过fs模块来和文件系统进行交互。
  • 该模块提供了一些标准文件访问api来打开、读取、写入文件,以及与其交互。
  • 使用文件系统,需要先引入fs模块,fs是核心模块,直接引入不需要下载。
  • 要使用fs模块,首先需要对其进行加载:const fs = require("fs")

同步和异步调用

  • fs模块中所有的操作都有两种形式可供选择
  • 同步文件系统会阻塞程序的执行,也就是除非操作完毕,否则不会向下执行代码。
  • 异步文件系统不会阻塞程序的执行,而是在操作完成时,通过回调函数将结果返回。

同步文件的写入

  • 创建或打开文件
    • fs.openSync(path, flags[, mode])
    • path:要打开文件的路径。
    • flags:打开文件要做的操作的类型,r是可读的,w是可写的。
    • mode(选填):设置文件的操作权限,一般不传。
    • 该方法会返回一个文件的描述作为结果,我们可以通过该描述符来对文件进行各种操作
  • 向文件中写入内容
    • fs.writeSync(fd, sring[, position[, encoding]])
    • fd:文件的描述符,需要传递要写入的文件的描述符
    • string:要写入的内容
    • position(选填):写入的起始位置
    • encoding(选填):写入的编码
  • 保存并关闭文件
    • fs.closeSync(fd)

异步文件的写入

  • 创建或打开文件
    • fs.openSync(path, flags[, mode], callback)
    • 异步调用的方法,结果都是通过回调函数返回的
    • 回调函数有两个参数:
      • err:错误对象,如果没有错误则为null
      • fd:文件的描述符
  • 向文件写入内容
    • fs.write(fd, sring[, position[, encoding]], callback)
  • 关闭文件
    • fs.close(fd, callback)
fs.open('hello.txt', 'w', function(err, fd) {
  if(!err) {
    fs.write(fd, '这是异步写入的内容~~~~', function(err) {
      if(!err) {
        console.log('写入成功~~~')
        fs.close(fd, function(err) {
          if(!err) {
            console.log('文件已关闭~~~')
          }
        })
      }
    })
  }else {
    console.log(err)
  }
})

简单文件写入

  • 同步:fs.writeFileSync(file, data[, options])
  • 异步:fs.writeFile(file, data[, options], callback, callback)
  • file:需要操作的文件的路径
  • data:需要写入的数据
  • options:可选,可以对写入进行一些设置
  • callback:当写入完成以后执行的函数
fs.writeFile('hello.txt', '这是通过writeFile写入的内容~~~', function(err) {
  if(!err) {
    console.log('写入成功,文件已关闭~~~')
  }
})

流式文件写入

  • 创建一个可写流
    • fs.createWriteStream(path[, options])
    • path:文件路径
    • options:配置的参数
  • 向文件中输出内容
    • ws.write('通过可写流写入文件的内容')
  • 关闭流
    • ws.end()
var ws = fs.createWriteStream('C:/Users/Administrator/Desktop/node/hello.txt')

ws.once('open', function() {
  console.log('流打开了~~~')
})

ws.once('close', function() {
  console.log('流关闭了~~~')
})

ws.write('通过可写流写入文件的内容')
ws.write('通过可写流写入文件的内容')
ws.write('通过可写流写入文件的内容') 

// 关闭流
ws.end()

简单文件读取

  • 同步读取:fs.readFileSync(path[, options])
  • 异步读取:fs.readFile(path[, options], callback)
    • path:要读文件的路径
    • options:读取的选项
    • callback:回调函数,通过毁掉函数将读取到的内容返回(err,data)
fs.readFile('an.jpg', (err, data) => {
  if(!err) {
    fs.writeFile('hello.jpg', data, function(err) {
      if(!err) {
        console.log('拷贝图片成功~~~')
      }
    })
  };
})

流式文件读取

// 创建一个可读流
var rs =  fs.createReadStream('an.jpg');

var as = fs.createWriteStream('a.jpg');

var qs = fs.createWriteStream('q.jpg');

rs.once('open', function() {
  console.log('可读流打开了~~~')
})

rs.once('close', function() {
  console.log('可读流关闭了~~~')
  // 数据读取完毕,关闭可写流
  as.end()
})

as.once('open', function() {
  console.log('可写流打开了~~~')
})

as.once('close', function() {
  console.log('可写流关闭了~~~')
})

// 如果要读取一个可读流中的数据,必须要为可读流绑定一个data事件,data事件绑定完毕,他会自动开始读取数据
rs.on('data', function(data) {
  as.write(data);
})

// pipe()可以将可读流中的内容,直接输出到可写流中
rs.pipe(qs)

fs模块的其他方法

  • existsSync(path):检查一个文件是否存在
  • stat(path, callback)statSync((path):获取文件信息
  • unlink(path, callback )unlinkSync(path):删除文件
  • readdir(path[, options], callback)readdirSync(path[, options]):读取一个目录的目录结构
  • truncate(path, len, callback)truncateSync(path, len):截断文件,将文件修改为指定大小
  • mkdir(path[, mode], callback)mkdirSync(path[, mode]):创建一个目录
  • rmdir(path, callback)rmdirSync(path):删除一个目录
  • rename(oldPath, newPath, callback)renameSync(oldPath, newPath):对文件进行重命名
  • watchFile(filename[, options], listenerCallback ):监事文件的修改


这篇关于Node.js的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程