标签「Node.js」(共 4 篇文章)

Node.js 中的很多核心模块,都是基于事件来实现的。一些对象通过触发一些事件,使得相应的监听器函数能够被调用执行。所有能够触发事件的对象都是 EventEmitter 类的实例。这些对象可以通过 eventEmitter.on() 方法,将多个函数附加到由这个对象触发的对应命名事件中。当 EventEmitter 对象触发一个事件时,所有附着在那个事件上的函数都会被同步调用。

下面的例子展示了一个简单的 EventEmitter 实例,其中包含一个单独的监听器。eventEmitter.on() 方法用来注册监听器, eventEmitter.emit() 方法用来触发相应的事件。

一般不会直接使用 EventEmitter 作为构造实例的对象,而是会通过继承来自定义一个 EventEmitter,使用方式如下:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('an event occurred!');
});
myEmitter.emit('event');

// 允许对同一事件添加多个监听器函数,
// 也允许通过事件来传递多个参数:
myEmitter.on('event', (a, b, c) => {
    // Something
})
myEmitter.emit('event', 'a', 'b', 'c');

在 TypedArray (ES6) 之前,JavaScript 语言还不能直接从二进制数据流中读取数据。Buffer 模块就被用来作为 Node 的核心 API,负责一些如 TCP 流和文件操作的功能。

在 ES6 的 TypedArray 出现后,Buffer 模块也继承了 Uint8Array,并且让它更适用于 Node.js 的场景。

Buffer 模块是 Node.js 中的全局对象,所以不需要像其它模块那样通过 require('buffer').Buffer 这样来导入 Buffer 模块,直接就能作为已存在的全局对象够使用。

Buffer 的实例与整数数组很相似,但是却有着固定的长度,一旦被创建就不能够改变大小。Buffer 在内存分配的位置上也有所不同,它并不是被 V8 分配在堆上,所以不存在受到 V8 内存限制的问题。它是由 Node 的 C++ 层面上来实现对内存的申请的,然后通过 JavaScript 来对内存进行分配。

在浏览器中,顶级作用域就是全局作用域。也就是说在全局作用域中通过 var something 会定义一个全局可访问的变量,这个变量会附加到全局对象 window 成为它的一个属性。

Node.js 采用 CommonJS 模块加载机制,一个文件对应一个模块。顶级作用域并不是全局作用域,而是模块作用域。在一个模块被加载前,会被 Node.js 使用一个匿名函数包裹:

(function (exports, require, module, __filename, __dirname) {
    // 模块文件的代码
})

因为有了这一个匿名函数的存在,而函数内部具有单独的作用域,因而有了模块作用域一说,这也是 Node.js 不同于浏览器的一点。

React 的好处很多,组件化简化了开发,虚拟 DOM 提升了页面性能,等等。当然,React 也有其缺点,其中影响最大的一点便是由于 React 是一个非常重型的框架,超过 2w 行的代码,即便是压缩后也超过 300k,导致了它的初始化加载非常费时。光是把这样的一个 JS 打包文件加载出来就要耗费一大笔时间,跟何况它的初始化执行过程也要达到百毫秒级,这样还是很影响用户体验的。

那么有没有什么方法能避免 React 这样的不足之处呢?

React 的渲染机制和其它类型的 MV * 框架有很大的区别。通过由数据构成的虚拟 DOM,React 便可在浏览器中一个根节点上渲染出一个完整的真实 DOM 树,从而完成整个页面的渲染。这是在浏览器客户端中完成的渲染操作。而在服务器(Node.js 环境)上,虽然没有 DOM,在客户端初次请求时,可以通过虚拟 DOM,将组件和数据渲染成真实 DOM 的 HTML 字符串,像其它后端语言如 PHP 那样把一个完整的 HTML 页面传输给浏览器,这就是服务端渲染。这同时也给了 React 一个很大的优势,让一个前端 View 层也有了 SEO 友好的展现方式。

Copyright © 2017 dremy.cn
皖ICP备16015002号