node.js 史上最详细 (博主持续更新)

1、node.js介绍

诞生于2009年,它不是一门语言也不是一门框架,它是基于Google V8引擎的JavaScript运行时环境,同时结合Libuv拓展了JavaScript功能,使之支持IO,fs等语言才有的特性,使得JavaScript能够同时具有DOM操作(浏览器)和I/O,文件读写、操作数据库等能力。

应用:淘宝双十一、去哪儿网PC端核心业务;前端工具 VScode、webpack等具有Node.js开发

node的包管理工具npm成为世界中开源包管理中最大的生态、功能强大。

2、特点

  • 事件驱动
  • 非阻塞IO模型(异步)
  • 轻量和高效

3.、在一线企业中的应用

①作为中间层

②做一些小型网站的后端 

  • 减少客户端内存,不会像MVVM模式的项目把页面渲染和数据请求都压在客户端,而是在服务端完成
  • SEO性好,不像mvvm模式页面由js生成,而是在服务端渲染好html字符,有利于网页被搜索到
  • 前端可以操控的范围增多,甚至可以操作服务器,数据层面的优化,比如中间层使用nginx、redis来优化项目,应对高并发。

优点:中间层模式是一种开发模式上的进步,但这种好的模式成本过高,如果没有一定量级的项目没必要使用 

4、node.js中的module.exports和exports

  •  Node中每个模块都有一个module对象,module对象中有一个exports属性作为借口对象,我们需要把模块之间公共方法或属性挂载到这个接口对象中,方便其他的模块使用 这些公共的方法或属性。
  • Node中每个模块的最后,都会return module.exports, 默认module.exports = {}
  • Node中每个模块都会把module.exports指向的对象赋值给一个变量exports,即module.exports == exports
  • module.exports == XX,表示当前模块导出一个单一成员,require导入的就是一个{ ... }
  • 如果需要导出多个成员,必须使用module.exports.xxx = xxx。

5、node、js中require加载第三方包的规则

  • 找写require文件同级目录中的node_module下面的同名文件,同级目录中没有node_module,就找父级(父级、祖父级等)的node_module

  • 找该文件夹下面package.json中的main,这个main属性值就是你引入的文件路径

6、npm 常见命令

npm 全名为node package manager,我们平时开发项目都需要使用npm命令安装依赖

7、文件读取(同步读取)

  • 使用fs.readFileSync()读取文件,第一个参数为文件名或文件描述符,第二个参数是一个对象,该对象有两个属性,一个是encoding,一个是flag(是读取文件--“r”,还是文件写入--“w”,还是追加--“a”)。官方文档该方法描述如下:

  • 读取文件写法如下
const fs = require("fs");
const content = fs.readFileSync("txt.txt", {flag: 'r'});
console.log(content.toString());

或者(指定encoding的编码格式需要与读取文件的编码格式一致,因为此例中的txt.txt文件格式是utf-8,所以我们指定utf-8之后可直接输出)

const fs = require("fs");
const content = fs.readFileSync("txt.txt", {flag: 'r', encoding: "utf-8"});
console.log(content);


  • 输出的结果如下
PS C:\Users\tcsc6\Desktop\node_1> node .\index.js
这是一个txt.txt

 总结:readFileSync读取文件中如果不设置encoding编码方式,直接输出是一耳光Buffer缓冲区,需要使用toString转换成字符串进行展示或者是操作;如果在readFileSync中设置encoding编码方式,使不使用toString都会输出字符串。

8、文件读取(异步读取)

  • 使用fs.readFile()读取文件,第一个参数为文件名或文件描述符(必传);第二个参数是一个对象(可传可不传)该对象有两个属性,一个是encoding,一个是flag(是读取文件--“r”,还是文件写入--“w”,还是追加--“a”),如果不传,默认encoding为“utf-8”,默认flag为“r”,;第三个参数callback(必传),官方文档该方法描述如下:

  • 该方法读取如下:
const fs = require("fs");
fs.readFile('txt.txt', (err, data) => {
    if(err) {
        console.log(err);
    } else {
        console.log(data);
    }
    console.log("我证明javascript是单行执行!")
});
console.log("我证明他是异步!");
  • 输出结果为
PS C:\Users\tcsc6\Desktop\node_1> node .\index.js
我证明他是异步!
<Buffer e8 bf 99 e6 98 af e4 b8 80 e4 b8 aa 74 78 74 2e 74 78 74 20 20>
我证明javascript是单行执行!

总结:如果不指定编码方式默认输出为Buffer缓冲器,readFile是异步函数,javascript是单行执行。

  • 要输出utf-8格式的文本需要指定encoding为utf-8
const fs = require("fs");
fs.readFile('txt.txt', {encoding: "utf-8"}, (err, data) => {
    if(err) {
        console.log(err);
    } else {
        console.log(data);
    }
    console.log("我证明javascript是单行执行!")
});
console.log("我证明他是异步!");
  
  • 输出结果为正常的字符串
PS C:\Users\tcsc6\Desktop\node_1> node .\index.js
我证明他是异步!
这是一个txt.txt  
我证明javascript是单行执行!
  • 封装异步读取文件Promise
function readFileAsync(url) {
    return new Promise( (resolve, rejects) => {
        fs.readFile(url, {encoding: 'utf-8', flag: 'r'}, (err, data) => {
            if(!err){
                resolve(data);
            } else {
                rejects(err)
            }
        })
    })
}
readFileAsync("txt.txt").then( res => {
    console.log(res);
})

9、文件写入(跟文件读取一样,分异步和同步方法,因同步一般不会使用,下面只介绍异步方法)

  • writeFile文件写入,第一个参数是文件名称(必填),第二个参数为写入的数据(必填),第三个参数是编码方式和操作类型(flag :append --> a 追加 ;write --> w 文件写入),该参数是可选填,第四个参数是错误回调函数,官方此方法介绍如下图:

  • 实例操作:封装一个写入文件(追加方式)的promise函数(使用async 和 await)
const fs = require("fs");
const { resolve } = require("path");
const { rejects } = require("assert");
function writefs(url, data, flag = "a") {
    return new Promise((resolve, rejects) => {
        fs.writeFile(url, data, {encoding: "utf-8", flag}, err => {
            if(!err){
                resolve("写入成功!");
            } else {
                rejects(err);
            }
        })
    })
}
async function writeFileAsync() {
    let connect = await writefs("txt.txt", "吃饺子\n");
    console.log(connect);
    
    let connect1 = await writefs("txt.txt", "红烧狮子头\n");
    console.log(connect1);
    
    let connect2 = await writefs("txt.txt", "水饺\n");
    console.log(connect2);
    
}
writeFileAsync()
  • 输出
PS C:\Users\tcsc6\Desktop\node_1> node .\index.js
写入成功!
写入成功!
写入成功!

10、删除文件,同样只介绍异步删除文件 fs.unlink(path, callback)

  • 使用fs.unlink(path,callback),第一个参数是文件路径,第二个参数是回调函数(只有err)

  • 代码实例
const fs = require("fs");
fs.unlink("txt222.txt", () => {
    console.log("删除成功!");
})

  • 执行结果:

11、Buffer缓冲器(安全的alloc)

  • 解决的问题
  1. 数组不能进行二进制数据的操作
  2. 因为js数组一般不指定长度,数组地址存放在heap中,存放的地方也不连续,引用的时候效率就会降低,导致js数组不想Java、python等语言效率高
  3. buffer内存空间开辟出固定大小的内存,存放的是连续的引用的时候很容易找到,效率高
  • 官网方法

  • 实例及输出

const buf = Buffer.alloc(10);
buf[0] = "123";
buf[1] = "255";
console.log(buf);
console.log(buf.toString());
console.log(buf[0]);
console.log(buf[0].toString());

总结:Buffer.alloc(10)开辟10个字节的数组,数组的每一项都可以进行赋值,之后我们可以通过获取数组项的方法获取某一项;

12、同样的还有allocUnsafe,不安全Buffer缓冲器

  • 官网方法介绍

  • 实例

const unsafebuf = Buffer.allocUnsafe(10);
unsafebuf[0] = "123";
console.log(unsafebuf);
console.log(unsafebuf[0].toString() + "\n");

总结:Buffer.allocUnsafe()同样也可以通过传入数字进行给Buffer设置长度,获取的时候使用[0、、]方式获取。

13、读取文件目录(fs.readdir() )这里只介绍异步

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章