Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nodejs核心模块简介 #10

Closed
Vibing opened this issue Aug 16, 2019 · 0 comments
Closed

Nodejs核心模块简介 #10

Vibing opened this issue Aug 16, 2019 · 0 comments

Comments

@Vibing
Copy link
Owner

Vibing commented Aug 16, 2019

学习nodejs必须要掌握其核心,就像学JavaScript必须掌握函数、对象、数据类型、BOM、DOM等。

nodejs核心也不少,这里介绍几个核心:Events模块、fs模块、stream的使用、http模块。

Events

事件驱动、非阻塞异步IO是nodejs的特点,所以Events是非常重要的模块。并且node中绝大多数模块都继承了Events

事件是发布订阅模式的实现。在浏览器中,比如click事件

$('button').on('click',()=>{
    //处理click响应
})

当然你也可以自定义事件:

//自定义事件
$('div').bind('hello',()=>{
    alert('hello')
});

//触发事件
$('div').trigger('hello');

那么在 node 中如何使用 Events 模块的呢?
我们定义一个类,让它继承 Events

const EventEmit = require('events');

//定义一个播放器类
class Player extends EventEmit { }

const player = new Player();

//定义播放事件
player.on('play', ( param )=>{
    console.log(`播放器播放《${param}》`)
})

play.emit('play','海阔天空'); // 播放器播放《海阔天空》
play.emit('play','七里香');   // 播放器播放《七里香》

如果你想让事件只执行一次,可以使用 once :

//定义播放事件
player.once('play', ( param )=>{
    console.log(`播放器播放《${param}》`)
})

play.emit('play','海阔天空'); 
play.emit('play','七里香');  

此时 只会打印出 播放器播放《海阔天空》

上面也说了 node 中绝大多数模块都继承了 Events,比如 stream、fs、http等等,它们就像浏览器里的 click,是原生就有的,如果你接着往下看 会对发现很多用到事件的地方。

fs文件系统模块

fs 全拼是 file system文件系统
既然是文件系统,它的主要作用就是操作文件,比如文件的新增、修改内容、读写文件内容等。

fs.stat 获取文件夹及文件相关信息

查看文件夹信息

fs.stat('./logs', (err, stats) => {
  if (err) {
    console.log(err);
    return;
  }

  console.log('目录:', stats.isDirectory());
  console.log('文件:', stats.isFile());
  console.log('大小:', stats.size);
});

//打印结果
目录: true
文件: false
大小: 160

查看文件信息

fs.stat('./fs.js', (err, stats) => {
  if (err) {
    console.log(err);
    return;
  }

  console.log('目录:', stats.isDirectory());
  console.log('文件:', stats.isFile());
  console.log('大小:', stats.size);
});

//打印结果
目录: false
文件: true
大小: 2087

fs.mkdir 创建文件夹

// 创建目录
fs.mkdir("./logs", err => {
  if (err) {
    console.log(err);
    return;
  }
  console.log("logs目录创建成功");
});

fs.mkdir 是异步方法,如果你想同步创建可以使用 fs.mkdirSync

fs.mkdirSync('./logs2'); //同步创建文件夹

fs.writeFile 写入内容

fs.writeFile('./logs2/hello.log', '你好~', err => {
  if (err) {
    console.log(err);
    return;
  }
  console.log('写入成功');
});

注意: 若文件不存在则创建文件 若文件中有内容则覆盖

有时候我们不希望内容被覆盖,而是追加,那么可以使用 appendFile 方法。

fs.appendFile("./logs/hello.log", "hello~\n我是程序员", err => {
  if (err) {
    console.log(err);
    return;
  }
  console.log("写入成功");
});

fs.readFile 读取文件内容

// 读取文件内容
fs.readFile("./logs/hello.log", "utf8", (err, stats) => {
  if (err) {
    console.log(err);
    return;
  }
  console.log(stats);
});

fs.readdir 读取文件夹

// 读取文件夹
fs.readdir("./logs", (err, files) => {
  if (err) {
    console.log(err);
    return;
  }
  console.log(files); //返回一个包含所有文件名称的数组
});

//打印结果
[ 'data-write.json', 'data.json', 'traking.log' ]

fs.rename 修改文件名称

// 修改名称 把hello.log修改为tranking.log
fs.rename("./logs/hello.log", "./logs/traking.log", err => {
  if (err) {
    console.log(err);
    return;
  }

  console.log("改名成功");
});

删除目录下所有文件

// 删除目录下文件
fs.readdirSync("./logs").map(file => {
  // 删除文件unlink
  fs.unlink(`./logs/${file}`, err => {
    if (err) {
      console.log(err);
      return;
    }
    console.log("文件删除成功");
  });
});

删除文件夹

// 只能删除空目录 若目录里不为空则会报错 所以要先删除里面的文件 再删除文件夹
fs.rmdir("./logs", err => {
  if (err) {
    console.log(err);
    return;
  }
  console.log("目录删除成功");
});

Stream 流

流,可理解为水流。只不过这里是数据流。
流的意义在于三点:

  1. 有源头
  2. 有终点
  3. 从源头流到终点

使用 stream 读写文件

const fs = require('fs');

const fileReadStream = fs.createReadStream('./logs/data.json');
const fileWriteStream = fs.createWriteStream('./logs/data-write.json');


/* 通过文件流的事件方式 */
fileReadStream.on('data', chunk => {
  fileWriteStream.write(chunk); // 可写流写入文件 如果文件不存在则创建文件
});

fileReadStream.on('error', err => {
  console.log('错误:', err);
});

fileReadStream.on('end', () => {
  console.log('结束');
});

上面代码中建立了一个流:可读流--->可写流。它满足了上面说的三点:有源头(可读流)、有终点(可写流)、从源头到终点(一个文件里的数据流到了另一个文件里)。

代码中也能看出,Stream 其实也继承了 Events,它含有data、error、end等事件。

使用 pipe

我们把上面代码改一下

// 监听pipe事件
fileWriteStream.on('pipe', source => {
  console.log(source);
});

/* 通过pipe方式 */
fileReadStream.pipe(fileWriteStream);

pipe 可理解为水管,在可读流和可写流之间连接了水管,不需要再监听 data 事件,使用起来很方便 能达到同样的效果。

Http 模块

http 模块主要用于搭建 http 服务,处理用户请求信息等

使用 http 请求

const http = require('http');

// 使用发送http请求
const options = {
  protocol: 'http:',
  hostname: 'www.baidu.com',
  port: '80',
  method: 'GET',
  path: '/img/baidu_85beaf5496f291521eb75ba38eacbd87.svg'
};

let responseData = '';

const request = http.request(options, response => {
  console.log(response.statusCode); // 获取链接请求的状态码

  response.setEncoding('utf8');

  response.on('data', chunk => {
    responseData += chunk;
  });

  response.on('end', () => {
    console.log(responseData);
  });
});

request.on('error', error => {
  console.log(error);
});

request.end();

使用 http 创建服务

// 使用http创建服务器
const port = 3000;
const host = '127.0.0.1';

const server = http.createServer();

server.on('request', (request, response) => {
  response.writeHead(200, {
    'Content-Type': 'text/plain'
  });
  response.end('Hello World\n');
});

server.listen(port, host, () => {
  console.log(`Server running at https://${host}:${port}/`);
});

关于 Node 核心模块还有很多,比如 Buffer、crypto加密、global全局变量、net网络、os操作系统等等,只不过上面介绍的是使用频率非常高的模块。

后面文章会继续介绍,详情的api使用请参考官网

@Vibing Vibing closed this as completed Aug 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant