IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Node.js 基础 -> 正文阅读

[JavaScript知识库]Node.js 基础

一、Node.js是什么?和浏览器端JS有什么区别?

Node.js 是一个基于Chrome V8引擎的Javascript运行环境。使用了事件驱动,非阻塞式I/O模型。用于服务端的开发,例如数据库的访问,其它服务器的调用。

优点及适用场景:

  1. 处理高并发场景性能更佳。
  2. Node.js擅长任务调度,善于I/O,不善于计算。
  3. 与webSocket配合,开发长连接的实时交互应用程序。

缺点

  1. 不适合CPU密集应用
  2. 可靠性不高,一旦代码某个环节崩溃,整个系统都崩溃。

异同:

  1. 浏览器和 Node.js 均使用 JavaScript 作为其编程语言
  2. 在浏览器中,大多数时候做的是与 DOM 或其?? Web 平台 API(例如 Cookies)进行交互。 Node.js 中不存在这些,也没有?documentwindow、等其他的对象。
  3. Node.js 版本支持的所有现代的 ES6-7-8-9 JavaScript
  4. Node.js 使用 CommonJS 模块系统,而在浏览器中,使用 ES 模块标准。
  5. Node.js 中使用?require(),而在浏览器中则使用?import

二、Node.js三大特点

* 三个特点是相辅相成的,少一个都不行。

(1)单线程

  1. JavaPHP等服务端语言中,会为每一个客户端创建一个新的线程;而Node.js仅仅使用一个线程。
  2. 配合异步非阻塞I/O、事件驱动机制,让node.js程序上宏观上也是并行的。
  3. 好处:不再有线程的创建、销毁的时间开销
  4. 坏处:一个用户把线程搞崩了,整个服务就崩了

(2)异步非阻塞I/O

  1. 当某个I/O执行完毕时,以事件的形式通知执行I/O操作的线程,线程执行这个事件的回调函数。
  2. 为了处理异步I/O,线程必须有事件循环,不断地检查有没有未处理事件,依次予以处理。

什么是同步 vs 异步、阻塞vs非阻塞?

同步和异步关注的是消息通信机制

同步是指,在发出一个调用时,在没有得到结果之前,该调用就不返回。但一旦调用返回,就得到返回值了。

异步则相反,调用发出之后,调用者不会立刻得到结果,而是在调用发出之后,被调用者通过状态、通知来通知调用者,或者通过回调函数处理这个调用。

阻塞和非阻塞关注的是程序在等待调用结果(消息、返回值)时的状态。

阻塞调用指的是调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。

非阻塞调用指的是不能立刻得到结果之前,该调用不会阻塞当前线程。

场景举例:

同步阻塞:王大爷把水壶放到火上烧,然后啥也不干在那等,直到水开了他再去做别的事情。

同步非阻塞:王大爷把水壶放到火上之后就去看电视,时不时来瞅一眼水有没有开。

异步阻塞:王大爷去买了个响水壶,他把响水壶放在火上烧,然后也是等着水开,水开的时候水壶会发出声响。

异步非阻塞:王大爷把响水壶放在火上,然后就去看电视,这时他不用时不时来看一眼,因为水开的时候,响水壶会发出声音通知王大爷。

阻塞和非阻塞说明的是王大爷的状态;同步异步说明的是水壶的调用姿势。

水壶能在水烧好的时候主动响起,等同于异步能在结束时通知主线程并且回调,所以,异步一般配合非阻塞,能更好发挥其作用。

(3)事件驱动

http://nodejs.cn/learn/the-nodejs-event-loop

三、Node.js安装 vs 通过nvm管理多个版本的Node.js

一般在官网下载最新稳定版本安装包即可。但是,当不同项目使用不同版本的node.js时,就会有点麻烦了。我们可以通过nvm来管理不同版本的Node.js。

(1) 下载nvm-windows工具:https://github.com/coreybutler/nvm-windows/releases

(2)解压并安装下载好的nvm-setup.exe

(3) ?nvm? 查看是否安装好 nvm

??? nvm list available? 查看 各node.js版本

??? nvm install 14.17.3? 安装指定版本node.js

??? nvm use 14.17.3??? 使用指定版本node.js

(4) 坑点:nvm 安装了指定版本的node,但是却没有npm!!! 安装目录下的node_modules里啥也没有!!

(5) 解决方案:去node.js官网上下载对应的安装包,把node_modules目录下的内容原封不动地复制到通过nvm安装的对应版本的node.js下的node_modules目录中。把npm,npm.cmd,npx,npx.cmd 四个文件复制到node_modules同级目录中。

四、什么是模块化?

每个模块都是一个独立的功能体;

每个文件都是一个模块,有自己的作用域;

在一个文件里定义的变量,函数,类都是私有的,对其它文件不可见。

可以分为自定义模块、核心模块(内置模块)、第三方模块

五、自定义模块

module.exports 导出,其它文件通过 require引入

a.js

module.exports = {
  sayHi () {
    console.log("hello")
  },
  add (x, y) {
    return x + y
  },
  aa:"this is a.js"
}

b.js

const { aa, sayHi, add } = require("./a")
console.log(aa)
sayHi()
console.log(add(3,4))

六、Node.js常用内置模块

①fs模块:操作文件相关

  1. 操作文件API(?*前者是异步操作,后者加Sync的是同步操作,阻塞线程。)
    1. readFile/readFileSync? 读取文件内容
    2. writeFile/writeFileSync? 写入文件内容
    3. rename/renameSync??? 修改文件名、目录
    4. unlink/unlinkSync? 删除文件
    5. copyFile/copyFileSync? 复制文件
    6. mkdir/mkdirSync? 创建目录
    7. readdir/readdirSync? 读取目录
    8. rmdir / rmdirSync 删除非空目录
    9. stat / statSync? 获取文件或者目录的详细信息,返回一个stat对象

? ? ? ? ? ? ? ? ? ?stat.isFile()? 是否是一个文件

? ? ? ? ? ? ? ? ? ?stat. isDirectory() 是否是一个目录

?

// 1、引入核心模块 fs 文件及目录的增删改查
const fs = require("fs")

/**
 * 所有文件操作,没有加async,都是异步操作。
 * 1-1、文件写入
 * 参数1:文件名 string
 * 参数2:要写入文件的内容 string
 * 参数3(可选):{flag:"a"/"w"/"r"} 追加/写入/读取
 */
fs.writeFile("test.txt", "要写入文件中的内容", { flag: "w" }, (err) => {
  if (err) {
    return console.log(err)
  }
  console.log("写入成功");
})

/**
 * 1-2、文件读取
 * 参数1:文件名
 * 参数2(可选):编码格式
 * 参数3、回调
 */

fs.readFile("index.js", "utf-8", (err, data) => {
  if (err) {
    return console.log(err)
  }
  console.log(data.toString());
})

/**
 * 1-3、修改文件名
 */
fs.rename("test.txt", "demo.txt", err => {
  if (err) {
        return console.log(err)
  }
  console.log("修改成功");
})

/**
 * 1-4、删除文件
 */
fs.unlink("test.txt", err => {
  if (err) return console.log(err)
  console.log("删除成功");
})

/**1-5、复制文件:先读取再写入 */
fs.copyFile("demo.txt", "copy.txt", err => {
  if (err) return console.log(err)
  console.log("复制成功");
})

/**2-1、创建目录 */
fs.mkdir("testDir", err => {
  if (err) return console.log(err)
  console.log("创建成功");
})

/**2-2、修改目录 */
fs.rename("testDir","modifyDir" ,err => {
  if (err) return console.log(err)
  console.log("修改成功");
})

/**2-3、读取目录 */
fs.readdir("modifyDir", (err,data) => {
  if (err) return console.log(err)
  console.log(data) // 返回的是一个数组:[ 'modify.html', 'ttttt.txt' ]
})

/**2-4、删除目录(删除空目录) */
fs.rmdir("emptyDir", err => {
  if (err) return console.log(err)
  console.log("删除成功");
})

/**2-5、判断文件或者目录是否存在 */
fs.exists("modifyDir", exists => {
  console.log(exists); // 返回一个布尔值
})

/**2-6、获取文件或者目录的详细信息 */
fs.stat("index.js", (err, stat) => {
  if (err) return console.log(err)
  console.log(stat)
  // 是否是一个文件
  let res1 = stat.isFile()
  // 是否是一个目录
  let res2 = stat.isDirectory()
  console.log(res1,res2);
 })

/**2-7、删除非空文件夹
 * 思路:递归查找每一级,删除其下所有文件,最后删除空文件夹
 */
function removeDir (path) {
  const data = fs.readdirSync(path); 
  for (let i = 0; i < data.length; i++) {
    const url = path +"/"+ data[i]
    const stat = fs.statSync(url)   
    if (stat.isDirectory()) {
      removeDir(url)
    } else {
      fs.unlinkSync(url)
    }
  }
  fs.rmdirSync(path)
}
removeDir("modifyDir")

? ? ? 2.buffer类(处理二进制数据)

? ? ? ? ? ?计算机中所有内容都以二进制存储

? ? ? ? ? ?JS中没有描述二进制的变量

? ? ? ? ??

// buffer node中的一个类
// 1、通过alloc创建指定大小buffer
let buffer = Buffer.alloc(10) // <Buffer 00 00 00 00 00 00 00 00 00 00>
console.log(buffer);
// 2、通过字符串的形式创建
let buffer = Buffer.from('大家好') // <Buffer e5 a4 a7 e5 ae b6 e5 a5 bd>
console.log(buffer);
// 3、通过数组形式创建
let buffer = Buffer.from([0xe5 ,0xa4, 0xa7, 0xe5, 0xae, 0xb6, 0xe5, 0xa5, 0xbd])
console.log(buffer); //  <Buffer e5 a4 a7 e5 ae b6 e5 a5 bd>
// 4、buffer转字符串
console.log(buffer.toString());
// 5、乱码问题
let buffer1 = Buffer.from([0xe5, 0xa4, 0xa7, 0xe5])
let buffer2 = Buffer.from([0xae, 0xb6, 0xe5, 0xa5, 0xbd])
console.log(buffer1.toString()); // 乱码了
// 6、合并buffer
let buffer3 = Buffer.concat([buffer1, buffer2])
console.log(buffer3.toString());
// 7、使用string decoder 解决乱码问题
let { StringDecoder } = require("string_decoder")
let decoder = new StringDecoder()
let res1 = decoder.write(buffer1)
let res2 = decoder.write(buffer2)
console.log(res1); // 大
console.log(res2); // 家好

? ? ? ?3.stream 流

流是一种以高效的方式处理读/写文件、网络通信、或任何类型的端到端的信息交换。

在传统的方式中,当告诉程序读取文件时,这会将文件从头到尾读入内存,然后进行处理。使用流,则可以逐个片段地读取并处理(而无需全部保存在内存中)。

const?fs?=?require("fs")

const?rs?=?fs.createReadStream("./001.jpg")

const?ws?=?fs.createWriteStream("./copy.jpg")

rs.pipe(ws)

②url模块

③querystring模块

// 引入URL模块
const url = require("url")
// 引入查询字符串模块
const qs = require("querystring")
// 声明一个URL
const urlstring = "https://www.baidu.com:443/index.html?c=12&d=13#sadfsadf";
// 将URL解析成对象
const obj = url.parse(urlstring)
console.log(obj);
/**
 * Url {
  protocol: 'https:',
  slashes: true,
  auth: null,
  host: 'www.baidu.com:443',
  port: '443',
  hostname: 'www.baidu.com',
  hash: '#sadfsadf',
  search: '?c=12&d=13',
  query: 'c=12&d=13',
  pathname: '/index.html',
  path: '/index.html?c=12&d=13',
  href: 'https://www.baidu.com:443/index.html?c=12&d=13#sadfsadf'
}
 */
console.log(obj.query) // c=12&d=13

// 将查询字符串转换为对象
let resultObj = qs.parse(obj.query)
console.log(resultObj); // { c: '12', d: '13' }

④path模块

__dirname: 获取当前模块的绝对路径。

__filename: 获取当前模块的绝对路径和模块名称

path.basename():获取文件名部分

path.extname():获取文件的父文件夹

path.dirname():获取文件的扩展名

path.join():连接路径的两个或多个片段

⑤http模块

// 1、引入内置http模块 (这个模块提供了http服务)
const http = require('http')
// 2、创建服务器,是个异步函数
const sever = http.createServer((req, res) => { 
  // req 表示 request 用户的请求
  // res 表示 response 服务器的相应
  // 3、 设置响应报文
  res.setHeader("Content-Type", "text/html; charset=UTF8")
  // 4、写入内容 
  res.write("<h1>Hello Node.js</h1>")
  res.write("<ul>")
  res.write("<li>Express</li>")
  res.write("<li>NPM</li>")
  res.write("<li>Koa</li>")
  res.write("</ul>")
  // 5、结束并发送响应 如果本次操作不结束,浏览器则一直显示载入中
  res.end()
})
// 6、设置监听端口
sever.listen(3000)

七、第三方模块

NodeJs社区或者第三方个人开发、我们可以直接使用的模块。

Node.js的第三方模块通常存在NPM中。Node.js内置了npm。

安装包:npm install module_name --save(-S)--dev(-D)

安装指定版本包:npm install module_name@version

卸载包:npm uninstall module_name

package.json: 记录当前项目所依赖的模块的版本信息

package-lock.json:记录了node_modules目录下所有模块的具体来源、版本号及其它信息

两者保证了在协同开发时,大家所依赖的模块版本是一致的。

热更新工具:npm install nodemon -g

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-23 10:38:28  更:2021-07-23 10:40:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 7:32:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码