企业级项目开发中的交互式解释器以及global全局定义、Stream流的合理运用和实战【Note.js】

简介: 企业级项目开发中的交互式解释器以及global全局定义、Stream流的合理运用和实战【Note.js】

交互式解释器

Read Eval Print Loop:节点。Js REPL(Read-Eval Print Loop:交互式解释器)表示一个计算机环境,类似于Windows系统或Unix/Linux shell的终端,我们可以在其中输入命令并接收系统响应。
REPL的交互式编程环境可以实时验证您的代码,这非常适合验证Node J和JavaScript相关的API。

$ node
> 1 +4
5
> 5 / 2
2.5
> 3 * 6
18
> 4 - 1
3
> 1 + ( 2 * 3 ) - 4
3
>

该节点带有交互式解释器,可执行以下任务:
读取-读取用户输入,解析输入的Javascript数据结构并将其存储在内存中。

$ node
> var x = 0
undefined
> do {
... x++;
... console.log("x: " + x);
... } while ( x < 5 );
x: 1
x: 2
x: 3
x: 4
x: 5
undefined
>

Execute-执行输入的数据结构
打印-输出结果
循环-循环上述步骤,直到用户按下ctrl-c按钮两次退出。
Node的交互式解释器可以很好地调试Javascript代码。
开始学习REPL
我们可以输入以下命令来启动节点的终端:

$ node
> var x = 10
undefined
> var y = 20
undefined
> x + y
30
> var sum = _
undefined
> console.log(sum)
30
undefined
>

global全局定义

__filename当前模块的文件名——解析的绝对路径。
这不必与主程序命令行中使用的名称相同。__目录名以获取当前模块的目录名。
例如:
执行节点示例。js在/Users/mjr目录中

console.log(__filename);
// Prints: /Users/mjr/example.js
console.log(__dirname);
// Prints: /Users/mjr

给定两个模块:a和b,其中b是a的依赖项。
文件目录结构如下:
/用户/mjr/app/a.js
/用户/mjr/app/node_modules/b/b.js
B、 js__对文件名的引用将返回/Users/mjr/app/node_modules/B/B。Js a.Js__对文件名的引用将返回/Users/mjr/app/a.Js

单元导出对象由模块系统创建。有时这是不可接受的;许多人希望自己的模块是一个类的实例。要实现这一点,需要将预期的导出对象分配给模块导出请注意,将预期对象分配给导出将只需重新绑定本地导出变量,这可能不是预期的。
例如,假设创建了一个名为.js的模块:

const EventEmitter = require('events');

module.exports = new EventEmitter();

// 处理一些工作,并在一段时间后从模块自身触发 'ready' 事件。
setTimeout(() => {
  module.exports.emit('ready');
}, 1000);
const a = require('./a');
a.on('ready', () => {
  console.log('模块 a 已准备好');
});

exports变量在模块的文件级范围内有效。在执行模块之前将其分配给模块导出的值。
它有一个模块的快捷方式。导出F=…可以更简洁地写成导出F=注意,就像任何变量一样,如果为导出分配了新值,则它将不再绑定到module.exports:

module.exports.hello = true; 
exports = { hello: false }; 

从对模块的引用中导出。
不导出,只在模块内有效
模块代码在这。在这个例子中,定义了一个函数。
此时,exports 不再是一个 module.exports 的快捷方式,且这个模块依然导出一个空的默认对象。

function require(/* ... */) {
  const module = { exports: {} };
  ((module, exports) => {
   function someFunc() {}
    exports = someFunc;
    module.exports = someFunc;
    // 此时,该模块导出 someFunc,而不是默认对象。
  })(module, module.exports);
  return module.exports;
}

Stream流的运用

流是一个节点,Js是一个非常重要的模块,它被广泛使用。
流是一个抽象接口,由Node中的许多对象实现。例如,向http服务器发起请求的请求对象是Stream和stdout(标准输出)。
此抽象接口是可读的、可写的或两者兼有。通过这些接口,我们可以与磁盘文件、套接字和HTTP请求交互,以实现数据从一个地方流到另一个地方的功能。

var fs = require("fs");
var data = '';

// 创建可读流
var readerStream = fs.createReadStream('input.txt');

// 设置编码为 utf8。
readerStream.setEncoding('UTF8');

// 处理流事件 --> data, end, and error
readerStream.on('data', function(chunk) {
   data += chunk;
});

readerStream.on('end',function(){
   console.log(data);
});

readerStream.on('error', function(err){
   console.log(err.stack);
});

console.log("程序执行完毕");
var fs = require("fs");
var data = 'W3Cschool教程官网地址:www.w3cschool.cn';

// 创建一个可以写入的流,写入到文件 output.txt 中
var writerStream = fs.createWriteStream('output.txt');

// 使用 utf8 编码写入数据
writerStream.write(data,'UTF8');

// 标记文件末尾
writerStream.end();

// 处理流事件 --> data, end, and error
writerStream.on('finish', function() {
    console.log("写入完成。");
});

writerStream.on('error', function(err){
   console.log(err.stack);
});

console.log("程序执行完毕");

执行结果如下:

$ node main.js 
程序执行完毕
写入完成。

事件

大多数节点js核心API都采用传统的异步事件驱动架构。某些类型的对象(触发器)会周期性地触发命名事件以调用函数对象(侦听器)。
例如,net每次有新连接时,服务器对象都会触发一个事件;fs。ReadStream将在文件打开时触发事件;当数据可读时,流对象触发事件。
所有可以触发事件的对象都是EventEmitter类的实例。这些对象打开一个eventEmitter On()函数,该函数允许一个或多个函数绑定到将由对象触发的命名事件。事件名称通常是骆驼字符串,但也可以使用任何有效的JavaScript属性名称。

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('触发了一个事件!');
});
myEmitter.emit('event');
const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
  console.log(a, b, this);
  // 打印:
  //   a b MyEmitter {
  //     domain: null,
  //     _events: { event: [Function] },
  //     _eventsCount: 1,
  //     _maxListeners: undefined }
});
myEmitter.emit('event', 'a', 'b');

EventEmitter将按照注册的顺序同步调用所有侦听器。因此,有必要确保事件的正确顺序,避免竞争条件或逻辑错误。侦听器函数可以使用setImmediate()或process。nextTick()方法切换到异步操作模式:

const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
  setImmediate(() => {
    console.log('这个是异步发生的');
  });
});
myEmitter.emit('event', 'a', 'b');
相关文章
|
30天前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理与实战
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
|
3天前
|
前端开发 JavaScript
用HTML CSS JS打造企业级官网 —— 源码直接可用
必看!用HTML+CSS+JS打造企业级官网-源码直接可用,文章代码仅用于学习,禁止用于商业
30 1
|
21天前
|
JavaScript 前端开发 开发者
探索JavaScript原型链:深入理解与实战应用
【10月更文挑战第21天】探索JavaScript原型链:深入理解与实战应用
26 1
|
1月前
|
SQL 前端开发 JavaScript
Nest.js 实战 (十五):前后端分离项目部署的最佳实践
这篇文章介绍了如何使用现代前端框架Vue3和后端Node.js框架Nest.js实现的前后端分离架构的应用,并将其部署到生产环境。文章涵盖了准备阶段,包括云服务器的设置、1Panel面板的安装、数据库的安装、域名的实名认证和备案、SSL证书的申请。在部署Node服务环节,包括了Node.js环境的创建、数据库的配置、用户名和密码的设置、网站信息的填写、静态网站的部署、反向代理的配置以及可能遇到的常见问题。最后,作者总结了部署经验,并希望对读者有所帮助。
127 11
|
1月前
|
存储 JavaScript 前端开发
前端开发:Vue.js入门与实战
【10月更文挑战第9天】前端开发:Vue.js入门与实战
|
13天前
|
前端开发 JavaScript
JavaScript新纪元:ES6+特性深度解析与实战应用
【10月更文挑战第29天】本文深入解析ES6+的核心特性,包括箭头函数、模板字符串、解构赋值、Promise、模块化和类等,结合实战应用,展示如何利用这些新特性编写更加高效和优雅的代码。
31 0
|
1月前
|
数据采集 JSON 前端开发
JavaScript逆向爬虫实战分析
JavaScript逆向爬虫实战分析
|
1月前
|
前端开发 JavaScript API
JavaScript逆向爬取实战——使用Python实现列表页内容爬取(二)
JavaScript逆向爬取实战——使用Python实现列表页内容爬取(二)
|
1月前
|
前端开发 JavaScript API
JavaScript逆向爬取实战——使用Python实现列表页内容爬取(一)
JavaScript逆向爬取实战——使用Python实现列表页内容爬取(一)
|
2月前
Nest.js 实战 (十三):实现 SSE 服务端主动向客户端推送消息
这篇文章介绍了在Nest.js应用中使用Server-Sent Events (SSE)的技术。文章首先讨论了在特定业务场景下,为何选择SSE而不是WebSocket作为实时通信系统的实现方式。接着解释了SSE的概念,并展示了如何在Nest.js中实现SSE。文章包含客户端实现的代码示例,并以一个效果演示结束,总结SSE在Nest.js中的应用。
Nest.js 实战 (十三):实现 SSE 服务端主动向客户端推送消息