js console 输出到文件_Node.js核心入门

70deee98755be4ce04ac7a58f9df75c4.png

正文

核心模块是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.argv
process.argv.forEach((val, index) => {
console.log(`${index}: ${val}`);
});

复制代码

则命令行运行时这样的:

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

0: /usr/local/bin/node
1: /Users/mjr/work/node/process-args.js
2: one
3: two=three
4: 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,world
console.log('hello%s', 'world');
// helloworld
console.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,world
myConsole.log('hello%s', 'world');
// helloworld
myConsole.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

2beeb452ceb68471096ea1b734cb19b7.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/541613.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

eclipse中项目内存溢出问题

2019独角兽企业重金招聘Python工程师标准>>> SpringBoot项目热启动Perm区内存溢出。 Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method jpaVendorAdapter threw exception; nested exception is java.lang.OutOfMemoryErro…

express rest_Express / Node中用于REST API的邮递员工具

express restWhen dealing with routes (like in express), we may use any of the REST verbs and at times, the browser is limited to facilitate testing the routes/REST API. 在处理路由时(如快速表达),我们可以使用任何REST动词,有时浏览器会受到…

形象易懂讲解算法I——小波变换

https://zhuanlan.zhihu.com/p/22450818?referdong5 最早发于回答:能不能通俗的讲解下傅立叶分析和小波分析之间的关系? - 咚懂咚懂咚的回答现收入专栏。从傅里叶变换到小波变换,并不是一个完全抽象的东西,可以讲得很形象。小波变…

使用Linux命令行归档文件

存档文件 (Archiving Files) As we already understand what Compression (Compression techniques in Linux) is? We shall learn about Archives. We prefer compression as it is convenient to send file compressed through a network but sometimes it is not a smart w…

http缓存机制之304状态码

在网上看到一篇关于解释浏览器缓存更新机制304状态码的文章,里面说如果请求头中的If-Modified-Since字段和If-None-Match字段的值分别和响应头中的Last-Modified字段和Etag字段值一致,服务器就会返回304状态码(无响应体),浏览器就从本地读取缓…

计算机选配 注意事项,选择鼠标注意事项有哪些

选择鼠标注意事项有哪些每台电脑旁边都有了一个忠实的伴侣,那就是“Mouse”--鼠标。选择鼠标最重要的一点就是质量,无论它的功能有多强大、外形多漂亮,如果质量不好那么一切都不用考虑了。那么,选择鼠标注意事项有哪些?笔记本鼠标…

js 验证护照_护照本地策略第2部分| Node.js

js 验证护照In my last article (Passport local strategy section 1 | Node.js), we started the implementation of the passport-local authentication strategy. We also looked at the various requirements to get started with the login form. In this article, we wil…

svn版利用什么技术实现_金葱粉涂料印花利用了什么技术?

金葱粉涂料印花利用了什么技术:金葱粉用涂料而不是用染料来生产印花布已经非常广泛,以致开始把它当作一种独立的印花方式。涂料印花是用涂料直接印花,该工艺通常叫做干法印花,以区别于湿法印花(或染料印花)。通过比较同一块织物上印花部位和未…

网站换服务器需要注意什么问题,网站更换服务器要注意哪些事项

原标题:网站更换服务器要注意哪些事项网站在运营的过程中,出于某种考虑,我们会将网站进行服务器的变更,那么在进行服务器变成过程中,需要注意哪些事项。一、如果是跨服务商更换网站服务器,需要做备案迁移。…

kafka分区与分组原理_大数据技术-Kafka入门

在大数据学习当中,主要的学习重点就是大数据技术框架,针对于大数据处理的不同环节,需要不同的技术框架来解决问题。以Kafka来说,主要就是针对于实时消息处理,在大数据平台当中的应用也很广泛。大数据学习一般都有哪些内…

ActiveReports 报表控件官方中文新手教程 (1)-安装、激活以及产品资源

本系列文章主要是面向初次接触 ActiveReports 产品的用户,能够帮助您在三天之内轻松的掌握ActiveReports控件的基本用法,包含安装、激活、创建报表、绑定数据源以及公布等内容。本篇文章我们就从安装产品開始带您开启轻松的 Ac…

如何在React Native中使用React JS Hooks?

In my articles, Im going to be using either expo or snack online IDE and android emulator. 在我的文章中,我将使用expo或点心在线IDE和android模拟器。 React Hooks is simply an awesome tool that helps us use states and other react features without w…

华为P40pro 手机云台_2020年目前拍照最好的手机推荐!华为P40 Pro!DXO全球榜首

目前最热门的拍照手机自然是华为P40 Pro,其相机性能直接问鼎DXOMARK手机相机评分榜首。对于拍照要极求高的用户,华为P40 Pro将是一个非常不错的选择。那么,华为P40 Pro除了出色的相机之外,其它方面表现如何呢?下面&…

Centos 7安装与配置nagios监控(一)

目 录序言(必备知识)一、安装规划1.1系统环境1.2所需软件包二、配置安装环境2.1同步时间2.2禁用SElinux2.3 xftp上传软件包2.4安装邮件服务三、监控主机安装3.1安装nagios的运行环境3.2增加用户3.3安装nagios3.4配置权限3.5安装插件3.6安装nrpe四、远程主机安装4.1配置运行环境…

备份linux系统报错_Linux 系统如何快速入门?分享民工哥总结的经验

大家好,我是民工哥。认识或熟悉我的人都知道,是做运维出身的,所以,很多时候,有很多朋友喜欢问我一些有关运维的问题,比如:我应该如何入门Linux系统运维?Linux系统运维到底需要学哪些…

pe联想服务器装系统教程视频,演示联想电脑u盘重装系统xp教程

联想电脑U盘重装XP系统的方法很多朋友询问,其实现在很多电脑已经不支持XP系统的安装了,如果你的联想电脑是近几年购买的,还是安装win10系统比较保险。当然联想电脑安装系统过程中遇到问题也可以联系人工客服。联想电脑如何使用U盘重装系统XP呢…

springboot公共模块打包_解决SpringBoot多模块发布时99%的问题?

每天都会分享Java架构文章,喜欢的朋友关注我。ps:文末有彩蛋,惊喜等着你如果使用的是 SpringBoot 多模块的项目,在发布的时候可能遇到各种各样的问题。本文归纳了以下 8 个原则和发布时经常出现的 4 个问题的解决方案,…

定义整型数组_C++数组的定义与初始化(学习笔记:第6章 01)

数组的定义与使用[1]数组是具有一定顺序关系的若干相同类型变量的集合体,组成数组的变量称为该数组的元素。数组的定义方括号里面列出的常量表达式是数组每一维的下标个数。数组的下标不管从哪一维它都是从0开始数的。例如:int a[10]; 表示a为整型数组&a…

我们正在经历一个应用疲惫时代?

在移动互联网时代到来之后,应用程序成为了智能手机必备,也正因为万千开发者的参与,才让移动终端充分发挥出了强大的能量,当然,这些开发者也不断创造着造富神话,一个小团队在几个月的努力之后可能就会成为亿…

语句拼接_第2课:一个周末学会R语言数据处理:表拆分和拼接

从一线收集了两百个文件,要整合到一起?总部一张全国两百个城市的汇总表,拆成两百个小文件?开什么玩笑,难道要复制粘贴到天荒地老。。。不用这么麻烦,一个循环,一个语句,实现快速表拆…