二. Node 编程基础 (未完)

本章主要讲的是
如何用模块组织代码;
异步编程的两种方式,回调和事件发射器;
异步逻辑的串行和并行控制方式;

1. 模块组织代码 module

  • Node模块打包代码是为了重用,但它不会污染全局作用域。模块允许从被引入文件中选择需要的函数和变量。
  • 模块即可以是一个文件,也可以是多个文件的目录。 如果模块是一个目录,Node默认会在这个目录下寻找一个叫index.js文件, 你也可以在这个目录下使用package.json文件指定模块的入口
  • 引入模块时,使用Node的require函数, 这个函数接收一个路径作为参数。 Node会以同步的方式,寻找文件,并加载文件内容。 查找顺序是 核心模块 -> 当前目录-> node_modules
  • 由于require是同步的,所以在I/O密集的地方应该尽量避免使用。同步操作通常放在程序最初加载的地方
  • exports 是对module.exports 的一个全局引用,被定义为一个可以添加属性的空对象。 真正导出的是module.exports。 因此导出对象时需要使用 module.exports, 如果直接使用exports将会打破引用, 无法导出。
module.exports = MyClass
//或者
module.exports = exports = MyClass
  • 同一个进程里require同一个模块得到的是相同的对象。Node能把模块作为对象缓存起来。如果程序里有两个文件引入了同一个模块,第一个require会把模块返回的数据保存到内存中,这样第二个require就可以直接从内存中取出来,不用再去寻找和运行模块了。

2. 回调

  • 回调通常用于处理一次性相应的逻辑。比如对于一次数据库查询,可以指定一个回调函数来处理查询的结果。
  • 通过创建中间函数来减少回调嵌套,便于测试、维护
  • 通过尽早返回(return)来减少嵌套

3. 事件监听器

  • 事件监听器本质上也是一个回调,不同之处是,它跟一个事件关联。例如Node的TCP socket,它有一个data事件, 当socket中有新数据就会触发,我们可以这样监听这个事件:
  socket.on('data', handleData)

一个简单的聊天室例子

const event = require("events");
const net = require("net");
const channel = new event.EventEmitter();

channel.clients = {};
channel.subscription = {};
channel.on("join", function(id, client) {
  // 保存client连接
  this.clients[id] = client;
  // 定义每个client的subscription方法, 如果sender不是自己就发送message
  this.subscription[id] = (sender_id, message) => {
    if (id != sender_id) {
      this.clients[id].write(message);
    }
  };
  /*
  每次客户端join进来都会使用上面定义subscription方法来绑定到broadcast事件
  有n个client连进来,这个broadcast事件就被监听n次,发射时,也会触发n次回调函数
  */
  this.on("broadcast", this.subscription[id]);  //broadcast事件处理回调
});
channel.on("leave", function(id) {
  channel.removeListener("broadcast", this.subscription[id]);
  channel.emit("broadcast", id, `${id} has left the chatroom \n`);
});

const server = net.createServer(client => {
  const id = `${client.remoteAddress}:${client.remotePort}`;
  channel.emit("join", id, client);
  client.on("data", data => {
    data = data.toString();
    // 当接收到客户端发来的数据时,向channel发射broadcast事件
    channel.emit("broadcast", id, data);
  });

  client.on("close", () => {
    channel.emit("leave", id);
  });
});

server.listen(8888);

4. 串行和并行的流程控制

5. 流程控制工具

你可能感兴趣的:(二. Node 编程基础 (未完))