正文

核心模块是Node.js的心脏,主要是有一些精简高效的库组成(这方面和Python有很大的相似之处),为Node.js提供了基础的API。主要内容包括:

Node.js核心入门(一)

  • 全局对象

  • 常用工具

  • 事件机制

Node.js核心入门(二)

  • 文件系统访问

  • HTTP服务器与客户端

全局对象

全局对象我想学过JavaScript的都知道在浏览器是window,在程序的任何地方都可以访问到全局对象,而在Node.js中,这个全局对象换成了global,所有的全局变量(除了global本身)都是global对象的属性。而我们在Node.js中能够直接访问的对象通常都是global的属性,如:console,process等。

全局对象与全局变量

global最根本的作用就是作为全局变量的宿主。按照ECMAScript规范,满足以下条件的变量即为全局变量:

  • 在最外层定义的变量(在Node.js中不存在,因为Node.js的代码在模块中执行,不存在在最外层定义变量)

  • 全局对象的属性

  • 隐式定义的变量(即未定义而直接进行赋值的变量)

当我们定义一个全局变量的时候,这个全局变量会自动成为全局变量的属性。

process

process 对象是一个全局变量,它提供当前 Node.js 进程的相关信息,以及控制当前 Node.js 进程。通常我们在写本地命令行程序的时候,少不了和它打交道。下面是它的最常用的成员方法:

1.process.argv

process.argv 属性返回一个数组,这个数组包含了启动Node.js进程时的命令行参数。第一个元素为process.execPath,第二个元素为当前执行的JavaScript文件路径,剩余的元素为其他命令行参数。

例如存储一个名为argv.js的文件:

// print process.argvprocess.argv.forEach((val, index) => {  console.log(`${index}: ${val}`);});

复制代码

则命令行运行时这样的:

$ node process-args.js one two=three four

0: /usr/local/bin/node1: /Users/mjr/work/node/process-args.js2: one3: two=three4: four复制代码

2.process.stdout

process.stdout是标准输出流,通常我们使用的console.log()输出打印字符,而process.stdout.write()函数提供了更为底层的接口。

process.stdout.write('请输入num1的值:');复制代码

3.process.stdin

process.stdin是标准输入流,初始时它是暂停的,要想从标准输入读取数据,我们必须恢复流,并手动编写流的事件响应函数。

/*1:声明变量*/var num1, num2;/*2:向屏幕输出,提示信息,要求输入num1*/process.stdout.write('请输入num1的值:');/*3:监听用户的输入*/process.stdin.on('data', function (chunk) {if (!num1) {        num1 = Number(chunk);        /*4:向屏幕输出,提示信息,要求输入num2*/        process.stdout.write('请输入num2的值');    } else {        num2 = Number(chunk);        process.stdout.write('结果是:' + (num1 + num2));    }});

复制代码

4.process.nextTick(callback[, ...args])

...args 调用 callback时传递给它的额外参数 process.nextTick()方法将 callback 添加到"next tick 队列"。一旦当前事件轮询队列的任务全部完成,在next tick队列中的所有callbacks会被依次调用。这种方式不是setTimeout(fn, 0)的别名。它更加有效率,因此别用setTimeout去代替process.nextTick。事件轮询随后的ticks 调用,会在任何I/O事件(包括定时器)之前运行。

console.log('start');process.nextTick(() => {  console.log('nextTick callback');});console.log('scheduled');

// start// scheduled// nextTick callback复制代码

console

console 模块提供了一个简单的调试控制台,类似于 Web 浏览器提供的 JavaScript 控制台。该模块导出了两个特定的组件:

  • 一个 Console 类,包含 console.log() 、 console.error() 和 console.warn() 等方法,可以被用于写入到任何 Node.js 流。

  • 一个全局的 console 实例,可被用于写入到 process.stdout 和 process.stderr。全局的 console 使用时无需调用 require('console')。(注意:全局的 console 对象的方法既不总是同步的(如浏览器中类似的 API),也不总是异步的(如其他 Node.js 流)。

比如全局下的常见的console实例:

console.log('hello,world');// hello,worldconsole.log('hello%s', 'world');// helloworldconsole.error(new Error('错误信息'));//  Error: 错误信息const name = '描述';console.warn(`警告${name}`);// 警告描述console.trace() // 向标准错误流输出当前的调用栈复制代码

常见的Console类:

const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err);

myConsole.log('hello,world');// hello,worldmyConsole.log('hello%s', 'world');// helloworldmyConsole.error(new Error('错误信息'));// Error: 错误信息const name = '描述';myConsole.warn(`警告${name}`);//警告描述

复制代码

常用工具 util

util 模块主要用于支持 Node.js 内部 API 的需求。大部分实用工具也可用于应用程序与模块开发者,用于弥补核心JavaScript的功能的不足。它的可以这样调用:

const util = require('util');

复制代码

1.util.inspect(object[, options])

util.inspect() 方法返回 object 的字符串表示,主要用于调试和错误输出。附加的 options 可用于改变格式化字符串的某些方面。它至少接受一个参数objet,即要转换的参数,而option则是可选的,可选内容如下:

  • showHidden 如果为 true,则 object 的不可枚举的符号与属性也会被包括在格式化后的结果中。默认为 false。

  • depth 指定格式化 object 时递归的次数。这对查看大型复杂对象很有用。默认为 2。若要无限地递归则传入 null。

  • colors 如果为 true,则输出样式使用 ANSI 颜色代码。默认为 false,可自定义。

  • customInspect 如果为 false,则 object 上自定义的 inspect(depth, opts) 函数不会被调用。默认为 true。

  • showProxy 如果为 true,则 Proxy 对象的对象和函数会展示它们的 target 和 handler 对象。默认为 false。

  • maxArrayLength 指定格式化时数组和 TypedArray 元素能包含的最大数量。默认为 100。设为 null 则显式全部数组元素。设为 0 或负数则不显式数组元素。

  • breakLength 一个对象的键被拆分成多行的长度。设为 Infinity 则格式化一个对象为单行。默认为 60。

例如,查看 util 对象的所有属性:

const util = require('util');console.log(util.inspect(util, { showHidden: true, depth: null }));

复制代码

2.util.callbackify(original)

util.callbackify(original)方法将 async 异步函数(或者一个返回值为 Promise 的函数)转换成遵循 Node.js 回调风格的函数。在回调函数中, 第一个参数 err 为 Promise rejected 的原因 (如果 Promise 状态为 resolved , err为 null ),第二个参数则是 Promise 状态为 resolved 时的返回值。例如:

const util = require('util');

async function fn() {return await Promise.resolve('hello world');}const callbackFunction = util.callbackify(fn);

callbackFunction((err, ret) => {if (err) throw err;  console.log(ret);});// hello world复制代码

注意:

  • 回调函数是异步执行的, 并且有异常堆栈错误追踪. 如果回调函数抛出一个异常, 进程会触发一个 'uncaughtException' 异常, 如果没有被捕获, 进程将会退出。

  • null 在回调函数中作为一个参数有其特殊的意义, 如果回调函数的首个参数为 Promise rejected 的原因且带有返回值, 且值可以转换成布尔值 false, 这个值会被封装在 Error 对象里, 可以通过属性 reason 获取。

function fn() {return Promise.reject(null);}const callbackFunction = util.callbackify(fn);

callbackFunction((err, ret) => {    // 当Promise的rejecte是null时,它的Error与原始值都会被存储在'reason'中。  err && err.hasOwnProperty('reason') && err.reason === null;  // true});复制代码

事件驱动 events

events是Node.js最重要的模块,原因是Node.js本身架构就是事件式的,大多数 Node.js 核心 API 都采用惯用的异步事件驱动架构,而它提供了唯一的接口,因此堪称Node.js事件编程的及时。events 模块不仅用于用户代码与 Node.js 下层事件循环的交互,还几乎被所有的模块依赖。

所有能触发事件的对象都是 EventEmitter 类的实例。这些对象开放了一个 eventEmitter.on() 函数,允许将一个或多个函数绑定到会被对象触发的命名事件上。事件名称通常是驼峰式的字符串,但也可以使用任何有效的 JavaScript 属性名。对于每个事件, EventEmitter支持 若干个事件监听器。当事件发射时,注册到这个事件的事件监听器被依次调用,事件参数作 为回调函数参数传递。

例如:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();// eventEmitter.on() 方法用于注册监听器myEmitter.on('event', () => {  console.log('触发了一个事件!');});// eventEmitter.emit() 方法用于触发事件myEmitter.emit('event');

复制代码

下面让我们来看看EventEmitter最常用的API:

  • EventEmitter.on(event, listener) 方法可以添加 listener 函数到名为 eventName 的事件的监听器数组的末尾。不会检查 listener 是否已被添加。多次调用并传入相同的 eventName 和 listener 会导致 listener 被添加与调用多次。

  • emitter.prependListener(eventName, listener)方法可以添加 listener 函数到名为 eventName 的事件的监听器数组的开头。不会检查 listener 是否已被添加。多次调用并传入相同的 eventName 和 listener 会导致 listener 被添加与调用多次。

  • eventEmitter.emit() 方法允许将任意参数传给监听器函数。当一个普通的监听器函数被 EventEmitter 调用时,标准的 this 关键词会被设置指向监听器所附加的 EventEmitter。

// 实例:const myEE = new EventEmitter();myEE.on('foo', () => console.log('a'));myEE.prependListener('foo', () => console.log('b'));myEE.emit('foo');// 打印://   b//   a复制代码
  • EventEmitter.once(event, listener) 为指定事件注册一个单次监听器,即监听器最多只会触发一次,触发后立刻解除该监听器。

server.once('connection', (stream) => {  console.log('首次调用!');});复制代码
  • EventEmitter.removeListener(event, listener) 移除指定事件的某个监听器, listener 必须是该事件已经注册过的监听器。(注意:removeListener 最多只会从监听器数组里移除一个监听器实例。如果任何单一的监听器被多次添加到指定 eventName 的监听器数组中,则必须多次调用 removeListener 才能移除每个实例。)

const callback = (stream) => {  console.log('有连接!');};server.on('connection', callback);// ...server.removeListener('connection', callback);

复制代码
  • EventEmitter.removeAllListeners([event]) 移除所有事件的所有监听器,如果指定 event ,则移除指定事件的所有监听器

const callback = (stream) => {  console.log('有连接!');};server.on('connection', callback);// ...server.removeListener('connection', callback);复制代码

error 事件

EventEmitter 定义了一个特殊的事件 error ,它包含了“错误”的语义,我们在遇到异常的时候通常会发射 error 事件。当 error被发射时,EventEmitter规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并打印调用栈。我们一般要为会发射 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。

var events = require('events');var emitter = new events.EventEmitter();emitter.emit('error');复制代码

继承EventEmitter

大多数情况下,我们不会直接使用EventEmitter,而是在对象中继承它,包括fs,http在内的只要是支持事件响应的核心模块都是EventEmitter的子类。这样做的原因有以下两个:

  • 具有某个实体功能的对象实现事件符合语义,事件的监听和发射应该是一个对象的方法。

  • JavaScript 的对象机制是基于原型的,支持部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。

来源:https://juejin.cn/post/6844903586283913230

js console 输出到文件_Node.js核心入门相关推荐

  1. c++读取utf8文件_Node.js 进阶之 fs 文件模块学习

    前言 文件操作是开发过程中并不可少的一部分.Node.js 中的 fs 模块是文件操作的封装,它提供了文件读取.写入.更名.删除.遍历目录.链接等 POSIX 文件系统操作.与其它模块不同的是,fs ...

  2. js bind 传参、_Node.js 在微医的应用场景及实践

    我是来自微医集团消费事业群的前端工程师高翔,这篇文章整理自我在<第一届缤纷前端技术沙龙>的主题分享<Node.js 在医疗行业的应用>,介绍了 Node.js 在微医的发展历程 ...

  3. node.js在注册表删除_Node.JS 11年:时间表和重要贡献

    node.js在注册表删除 Do you know 你知道吗 Node.js在2020年5月27日已满11岁 (Node.js has turned 11 on 27th May 2020) ? Ca ...

  4. js监听iframe关闭_Node.js文档NET[翻译]

    Node.js v12.0.0 Documentation​nodejs.org Net模块提供一个异步的网络API,这个API可以创建基于流的TCP,或者IPC服务器(net.createServe ...

  5. egg.js ajax上传文件,egg.js 通过 form 和 ajax 两种方式上传文件并自定义目录和文件名...

    一.需求 egg.js 的文件上传个人觉得很一般,内置的 multipart 插件并不怎么好用. egg-multipart 也是基于 co-busboy 实现的. egg 官方给的文件上传的示例地址 ...

  6. js怎样和硬件交互_Node.js与JavaScript

    有很多介绍nodejs的文章,也有很多教程,覆盖了服务器开发.桌面开发.移动端等等,但是鲜有文章明确的回答过一个问题:Node是什么? 这看起来是一个再简单过的问题了,真要答起来可不容易,不去深入研究 ...

  7. js动态载入css文件,原生JS动态加载JS、CSS文件及代码脚本(示例代码)

    var DynamciLoadUtil = { // 动态加载外部js文件,并执行回调 loadJS: function(url, callback){ var script = document.c ...

  8. js修改mysql数据库数据_Node.js操作mysql数据库增删改查

    关于node.js操作mysql数据库的相关介绍请阅读全文吧.下文介绍的非常详细,具体内容如下所示: 安装mysql模块 npm install mysql 数据库准备 mysql server所在的 ...

  9. js json制表符报错_Node.js一个好汉的三个帮

    npm npm是当之无愧的大哥,从Node.js出场的那一天开始就一起打天下.主要是帮Node.js管理包.最早它仅仅针对于Node.js项目,后来它的作用越来越大,把bower一些对手都干掉了,现在 ...

最新文章

  1. 新兴AI解决方案将越来越依赖于嵌入式视觉技术
  2. ASP.NET程序员职位要求!
  3. 1.1计算机系统简介
  4. jsp文件通常用common_JSP使用commons-fileupload实现文件上传实例
  5. 产品经理必备知识之如何用CREATE模型对用户进行行为分析
  6. Debug Pytorch: ValueError: Expected more than 1 value per channel when training, got input size tor
  7. RxSwift之UI控件UISlider与UIStepper扩展的使用
  8. php中__autoload()方法详解
  9. 【C++深度剖析教程11】C++学习之编写代码实现复数类
  10. 【mysql】悲观锁和乐观锁的实现原理
  11. namespace用法
  12. Bailian2972 确定进制(POJ NOI0113-34,POJ NOI0201-1973)【暴力+进制】
  13. 普通人快速拿到校招offer的十大狠招
  14. 可视化图布局算法简介
  15. 基于IHttpAsyncHandler的TCP收发器
  16. VMP3.6的反调试和反虚拟机
  17. 用python中的turtle库画蜡笔小新
  18. ROS-3DSLAM(十四)lvi-sam源代码阅读12 —— visual_loop阅读5
  19. Linux的主机名基础
  20. 云旗OS助手火了!可一站式体验统信UOS

热门文章

  1. 计算机组装过程英文版,计算机组装与维护试题及答案(国外英文资料).doc
  2. linux 磁盘分配 简书,linux 磁盘分区
  3. java 多个异常处理_Java 多个异常共享同一个异常处理器的方法
  4. android gradle错误,Android studio gradle错误与顶级异常
  5. python帮助文档中查看内置函数_PYTHON官方文档内置函数整理
  6. delphi 生成 超大量xml_用OpenCV4实现图像的超分别率
  7. day5-shutil模块
  8. 基于微服务架构,改造企业核心系统之实践
  9. 关于liaoxuefeng的python3教程实战第四天
  10. 介绍MFSideMenu左右滑动控件的使用