企业级项目开发中的交互式解释器以及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');
相关文章
|
2月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理与实战
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
|
15天前
Next.js 实战 (二):搭建 Layouts 基础排版布局
本文介绍了作者在Next.js v15.x版本发布后,对一个旧项目的重构过程。文章详细说明了项目开发规范配置、UI组件库选择(最终选择了Ant-Design)、以及使用Ant Design的Layout组件实现中后台布局的方法。文末展示了布局的初步效果,并提供了GitHub仓库链接供读者参考学习。
Next.js 实战 (二):搭建 Layouts 基础排版布局
|
9天前
|
存储 网络架构
Next.js 实战 (四):i18n 国际化的最优方案实践
这篇文章介绍了Next.js国际化方案,作者对比了网上常见的方案并提出了自己的需求:不破坏应用程序的目录结构和路由。文章推荐使用next-intl库来实现国际化,并提供了详细的安装步骤和代码示例。作者实现了国际化切换时不改变路由,并把当前语言的key存储到浏览器cookie中,使得刷新浏览器后语言不会失效。最后,文章总结了这种国际化方案的优势,并提供Github仓库链接供读者参考。
|
10天前
Next.js 实战 (三):优雅的实现暗黑主题模式
这篇文章介绍了在Next.js中实现暗黑模式的具体步骤。首先,需要安装next-themes库。然后,在/components/ThemeProvider/index.tsx文件中新增ThemeProvider组件,并在/app/layout.tsx文件中注入该组件。如果想要加入过渡动画,可以修改代码实现主题切换时的动画效果。最后,需要在需要的位置引入ThemeModeButton组件,实现暗黑模式的切换。
|
25天前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
29 2
|
1月前
|
前端开发 JavaScript
用HTML CSS JS打造企业级官网 —— 源码直接可用
必看!用HTML+CSS+JS打造企业级官网-源码直接可用,文章代码仅用于学习,禁止用于商业
124 1
|
2月前
|
JavaScript 前端开发 开发者
探索JavaScript原型链:深入理解与实战应用
【10月更文挑战第21天】探索JavaScript原型链:深入理解与实战应用
33 1
|
2月前
|
SQL 前端开发 JavaScript
Nest.js 实战 (十五):前后端分离项目部署的最佳实践
这篇文章介绍了如何使用现代前端框架Vue3和后端Node.js框架Nest.js实现的前后端分离架构的应用,并将其部署到生产环境。文章涵盖了准备阶段,包括云服务器的设置、1Panel面板的安装、数据库的安装、域名的实名认证和备案、SSL证书的申请。在部署Node服务环节,包括了Node.js环境的创建、数据库的配置、用户名和密码的设置、网站信息的填写、静态网站的部署、反向代理的配置以及可能遇到的常见问题。最后,作者总结了部署经验,并希望对读者有所帮助。
203 11
|
2月前
|
存储 JavaScript 前端开发
前端开发:Vue.js入门与实战
【10月更文挑战第9天】前端开发:Vue.js入门与实战
|
1月前
|
前端开发 JavaScript
JavaScript新纪元:ES6+特性深度解析与实战应用
【10月更文挑战第29天】本文深入解析ES6+的核心特性,包括箭头函数、模板字符串、解构赋值、Promise、模块化和类等,结合实战应用,展示如何利用这些新特性编写更加高效和优雅的代码。
45 0