【Node】常用基础 API 整理
一、Debug 调试方法
Node 的调试方法有很多,主要分为安装 node-inspect 包调试、用 Chrome DevTools 调试和 IDE 调试,可以在官网的 Docs Debugging Guide 查看安装方法。
下面介绍使用 Chrome DevTools 调试的方法,首先安装 Chrome Extension NIM,打开 Inspect 入口页面 chrome://inspect
写一个简单 debug.js 测试文件:
// apiTest/debug.js
console.log("this is debug test")
function test () {console.log("hello world")
}
test()
复制代码
使用node --inspect-brk
来启动脚本,-brk
相当于在程序入口前加一个断点,使得程序会在执行前停下来
$ node --inspect-brk apiTest/debug.js
Debugger listening on ws://127.0.0.1:9229/44b5d11e-3261-4090-a18c-2d811486fd0a
For help, see: https://nodejs.org/en/docs/inspector
复制代码
在 chrome://inspect 中设置监听端口 9229(默认),就可以看到可以 debug 的页面:
(function (exports, require, module, __filename, __dirname) {
console.log("this is debug test")
function test () {console.log("hello world")
}
test()
});
复制代码
如果我们使用node --inspect
来启动脚本,那整个代码直接运行到代码结尾,无法进行调试,但此时 Node 还进程没有结束,所以可以在 http://127.0.0.1:9229/json/list 查询 devtoolsFrontendUrl ,复制此 Url 到 Chrome 上进行调试。
看到使用 Chrome DevTools 的调试方法还是比较复杂的,一些 IDE 都支持直接断点调试,推荐WebStorm、VScode。
二、全局变量
在 Node 中常用的全局方法有 CommonJS、Buffer、process、console、timer 等,这些方法不需要 require
引入 API 就可以直接使用。
如果希望有属性或方法可以*“全局使用”*,那就将它挂载在 Node 的global
对象上:
global.gNum = 300
console.log(gNum); // 300
复制代码
在 Node 中所有模块都可以使用这些全局变量,以下就介绍 Node 中的全局变量
2.1 CommonJS 模块
Node CommonJS 模块规范根据实现了module
、exports
和require
模块机制。Node 对每个文件都被进行了模块封装,每个模块有自己的作用域,如在 debug 时看到的:
(function (exports, require, module, __filename, __dirname) { // some code
});
复制代码
模块机制中的 __dirname
、__filename
、exports
、module
、require()
这些变量虽然看起来是全局的,但其实它们仅存在于模块范围。需要注意的几点是:
- 模块内部
module
变量代表模块本身 - 模块提供
require()
方法引入外部模块到当前的上下文中 module.exports
属性代表模块对外接口,默认的快捷方式exports
简单的使用方式如下:
/* common_exports.js */
exports.num = 100
exports.obj = {a : 200
}
exports = {count : 300
}/* common_require.js */
const mod = require('./common_exports')
console.log(mod) // { num: 100, obj: { a: 200 } }
console.log(mod.count) // undefined
复制代码
注意到上例中的mod.count
为undefined
,这是因为exports
只是module.exports
的引用,可以给exports
添加属性,但不能修改exports
的指向。
更深入的了解模块机制可以看 【Node】前后端模块规范与模块加载原理
2.2 process 进程对象
process 包含了进程相关的属性和方法,Node 的 process 文档 中的内容特别多,列举几个常用方法。
Node 进程启动时传递的参数都在 process.arg
数组中:
// process.js
const {argv , execPath} = processargv.forEach((val, index) => {console.log(`${index}: ${val}`)
})
console.log(execPath)
复制代码
可以在执行 process.js 时传递其他参数,这些参数都会保存在argv
中:
$ node apiTest/process.js one=1 --inspect --version
0: /usr/local/bin/node
1: /Users/mobike/Documents/webProjects/testNode/apiTest/process.js
2: one=1
3: --inspect
4: --version
/usr/local/bin/node
复制代码
process.argv
第一个参数就是 process.execPath
,即调用执行程序 Node 的路径,第二个参数时被执行的 JS 文件路径,剩下的就是自定义参数。
process.env
是包含运行环境各种参数的对象,可以直接输出env
查看所有参数信息,也可以输出某个属性:
const env = process.env
console.log(env.PATH) // /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/Documents/webProjects/testNode/node_modules/.bin
console.log(env.SHELL) // /bin/zsh
复制代码
在 webpack 打包过程中常用process.env.NODE_ENV
判断生产环境或开发环境,process.env
是没有NODE_ENV
这个属性的,你可以在系统环境变量中配置,也可以在项目程序直接设置process.env.NODE_ENV=‘dev’
。
process.cwd()
方法返回 Node.js 进程的当前工作目录,和 Linus 命令$ pwd
功能一样:
// process.js
console.log(process.cwd()) // /Users/Documents/webProjects/testNode
复制代码
$ node process.js
/Users/WebstormProjects/testNode
$ pwd
/Users/WebstormProjects/testNode复制代码
2.3 Timers 异步
Node 中的计时器方法与 Web 浏览器中的JS 计时器类似,但内部实现是基于 Node 的 Event Loop。Node 中的计时器有setImmediate()
、setTimeout()
、setInterval()
。
在 Node 中有一个轻量级的process.nextTick()
异步方法,它是在当前事件队列结束时调用, setImmediate()
是当前 Node Event Loop 结束时立即执行,那执行顺序有什么区别呢?
下面举例说明process.nextTick(fn)
与setImmediate(fn)
与setTimeout(fn,0)
之间的区别:
// timer.js
setImmediate(()=>{console.log("setImmediate")
});setTimeout(()=>{console.log("setTimeout 0")
},0);setTimeout(()=>{console.log("setTimeout 100")
},100);process.nextTick(()=>{console.log("nextTick")process.nextTick(()=>{console.log("nextTick inner")})
});
复制代码
看下执行结果:
$ node timer.js
nextTick
nextTick inner
setTimeout 0
setImmediate
setTimeout 100
复制代码
process.nextTick()
中的回调函数最快执行,因为它将异步事件插入到当前执行队列的末尾,但如果process.nextTick()
中的事件执行时间过长,后面的异步事件就被延迟。
setImmediate()
执行最慢,因为它将事件插入到下一个事件队列的队首,不会影响当前事件队列的执行。当setTimeout(fn, 0)
是在setImmediate()
之前执行。
2.4 Buffer 二进制
Buffer 对象用于处理二进制数据流。JS 没有处理二进制的功能,而 Node 中的一部分代码是由 C++ 实现的,所有 Node 中的 Buffer 性能部分用 C++ 实现,非性能部分由 JS 封装。
Buffer 实例类似整数数组,元素为十六进制的两位数(0~255),并且挂载在 global 对象上不需要 require就能使用。
最新的 Buffer API 使用Buffer.alloc(length, value)
创建固定长度为 length 的 Buffer 实例,value 默认填充 0,使用Buffer.from()
将其它类型数据转为 Buffer:
console.log(Buffer.alloc(5)) // <Buffer 00 00 00 00 00>
console.log(Buffer.alloc(5, 44)) // <Buffer 2c 2c 2c 2c 2c>
console.log(Buffer.from([3, 4, 5])) // <Buffer 03 04 05>
console.log(Buffer.from('test')) // <Buffer 74 65 73 74>
console.log(Buffer.from('测试')) // <Buffer e6 b5 8b e8 af 95>
复制代码
注意到字符串转 Buffer 时英文占一位,中文占三位,而不是四位,当中文乱码的时可以考虑没有正确读取 Buffer 流。
Buffer 类提供几个静态方法,Buffer.byteLength()
计算长度,Buffer.isBuffer()
做验证,Buffer.concat()
拼接 Buffer 实例:
const buf1 = Buffer.from([3, 4, 5])
const buf2 = Buffer.from('test')console.log(Buffer.byteLength('test')) // 4
console.log(Buffer.byteLength('测试')) // 6
console.log(Buffer.isBuffer('test')) // false
console.log(Buffer.isBuffer(buf1)) // true
console.log(Buffer.concat([buf1, buf2])) // <Buffer 03 04 05 74 65 73 74>复制代码
除此之外,Buffer 实例也有常用的属性和方法,类似 JS 中的 String,有length
、toString('base64')
、equals()
、indexOf()
等。
以上就是 Node 全局变量的概述,其他的 API 或内置模块都需要·
require('xxx')
引入使用,我们可以在 nodejs.cn 中查看关于 Global API 更详细的介绍。
三、基础 API
3.1 path 路径相关
path 是处理和路径相关问题的内置 API,可以直接require('path')
使用。以下示例常用的 path 方法。
对路径的处理常用path.normalize()
规范路径、path.join()
拼接路径,以及使用path.resolve()
将相对路径解析为绝对路径:
const path = require('path')
console.log(path.normalize('//asd\/das'), // /asd/daspath.join('user', 'local'), // user/localpath.resolve('./')) // /Users/Documents/webProjects/testNode/apiTest
复制代码
解析某个路径,可以用path.basename()
得到文件名称,path.extname()
得到后缀扩展名,path.dirname()
得到目录名:
const path = require('path')
const filePath = 'webProjects/testNode/apiTest/path.js'
console.log(path.basename(filePath), // path.js path.extname(filePath) // .js path.dirname(filePath), // webProjects/testNode/apiTest
)
复制代码
以上解析路径方法得到某个值,还可以使用path.parse()
完全解析路径为一个对象,path.format()
反向操作:
let sp = path.parse(filePath)
console.log(sp)
// { root: '',
// dir: 'webProjects/testNode/apiTest',
// base: 'path.js',
// ext: '.js',
// name: 'path' }
console.log(path.format(sp))
// webProjects/testNode/apiTest/path.js
复制代码
除此之外,还有对于系统路径的操作,使用path.sep
取得路径分隔符,路径片段分隔符,POSIX 上是/
, Windows 上是\
,path.delimiter
取得系统路径定界符,POSIX 上是:
,Windows 上是;
,示例如下:
console.log(filePath.split(path.sep))
// [ 'webProjects', 'testNode', 'apiTest', 'path.js' ]console.log(process.env.PATH) // 系统路径配置
// /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbinconsole.log(process.env.PATH.split(path.delimiter))
// [ '/usr/local/bin', '/usr/bin', '/bin', '/usr/sbin', '/sbin' ]
复制代码
以上就是 Node 对路径的常用操作,需要注意的是,在获取路径时有几种方式,得到的路径是不同的:
__dirname
、__filename
:总是返回文件绝对路径;process.cwd()
或$ pwd
:返回执行 Node 命令的文件夹;path.resolve('./')
:是相对 Node 启动文件夹,在require()
中./
是相对于当前文件夹;
3.3 events 事件
大部分 Node API 都采用异步事件驱动,所有能触发事件对象都是 EventEmitter 类的实例,通过 EventEmitter.on()
绑定事件,然后通过 EventEmitter.emit()
触发事件。
// apiTest/events.js
const Events = require('events')class MyEvents extends Events{
}
const event = new MyEvents()event.on('test-event',()=>{console.log('this is an event')
})event.emit('test-event')
setInterval(()=>{event.emit('test-event')
},500)
复制代码
执行以上代码会一直连续处罚 test-event 事件,当然还可以传递事件参数,并且可以传递多个参数。修改上诉代码如下:
event.on('test-event', (data, time) => {console.log(data,time)
})
event.emit('test-event', [1, 2, 3], new Date())
复制代码
$ node apiTest/events.js
[ 1, 2, 3 ] 2019-04-23T07:28:00.420Z
复制代码
同一个事件监听器可以绑定多个事件,触发时按照绑定顺序加入执行队列,并且可以使用EventEmitter.removeListener()
删除监听器的事件:
function fn1 () {console.log('fn1')
}
function fn2 () {console.log('fn2')
}
event.on('multi-event',fn1)
event.on('multi-event',fn2)setInterval(()=>{event.emit('multi-event')
},500)
setTimeout(()=>{event.removeListener('multi-event', fn2)
}, 600)
复制代码
$ node apiTest/events.js
[ 1, 2, 3 ] 2019-04-23T07:39:11.624Z
fn1
fn2
fn1
fn1
...
复制代码
3.4 fs 文件系统
Node 文件模块通过require('fs)
使用,所用方法都有同步和异步方法。
文件系统中的异步方法,第一个参数保留给异常,操作成功时参数值为null
或undefined
,最后一个参数就是回调函数。例如读取文件的fs.readFile()
和写文件的fs.writeFile()
示例如下:
const fs = require('fs')fs.readFile('./apiTest/fs.js', (err, data) => {if (err) throw errconsole.log('readFile done!!!')
})fs.writeFile('./apiTest/fs.txt', 'this is test file', {encoding: 'utf8'
}, (err) => {if (err) throw errconsole.log('writeFile done!!!')
})
复制代码
推荐 nodejs.cn 中的 Docs API 中文版查看更多 Node API 的使用。
加油呢少年~
【Node】常用基础 API 整理相关推荐
- linux常用基础命令整理
linux常用基础命令整理 su - 用户名 ->切换到指定用户下 ls ------>查看当前目录下的目录及文件 clear ------>清理屏幕 cd 路径 -----> ...
- 在linux系统环境中 常用的关机命令,Linux常用基础命令整理:关机命令、查看目录下文件命令等...
整理了一些Linux常用基础命令,欢迎指正. 首先记住四个热键,学会这四个键,收益一辈子. Tab按键---命令补齐功能 Ctrl+c按键---停掉正在运行的程序 Ctrl+d按键---相当于exit ...
- JAVA常用基础API(经典实例)
API文档注释写法 实例: package apidoc; /*** 在类上面写文档注释,是用来说明当前类的设计目的.功能* @author ta* @version 1.0* @see java.l ...
- 音视频学习之ffmpeg常用基础命令整理
基于windows环境安装好必要的ffmpeg后,对ffmpeg基础命令进行一些了解: 1:ffmpeg查看版本: ffmpeg -version 2:ffmpeg查询命令: 基本信息:ffmpeg ...
- Jedis常用API整理-详细
Jedis常用API整理 redis是一种高级的key-value的存储系统 其中的key是字符串类型,尽可能满足如下几点: 其中value 支持五种数据类型: jedis语法总结 1. jedis中 ...
- python常用变量名_python基础知识整理
Python Python开发 Python语言 python基础知识整理 序言:本文简单介绍python基础知识的一些重要知识点,用于总结复习,每个知识点的具体用法会在后面的博客中一一补充程序: 一 ...
- JavaScript一些常用 API整理汇总
JavaScript一些常用 API整理汇总 Array new Set() 数组去重 const arr = [3,4,4,5,4,6,5,7]; console.log(new Set(arr)) ...
- python常用api_[原创]IDAPython常用API整理
IDAPython常用API整理:通过一些脚本和<IDA Pro权威指南>,查阅官网的IDAPython API整理,不算很多,有待增添. idaapi.MinEA():获取载入程序的最小 ...
- java基础知识点整理一
java基础知识点整理一 引言 '''突然发觉任何一门语言的基础知识部分,都比较杂一些.如果个人经过梳理之后,知识体系系统化,可以让基础更加牢靠一些.但是还是会有一些遗忘.所以,我想把一些比较重要但是 ...
最新文章
- 云起作者微博认证在哪_UZI的期待实现了!厂长改认证明示复出,将再现“猪狗大战”荣光...
- 基于Windows 2008 R2 Core的SQL Server 2008 R2 Cluster部署(Step by Step)
- [音乐欣赏]Craigie Hill
- JSON.stringify()方法
- 数值计算 插值与拟合
- Tomcat实现session的代码逻辑分析
- 白硕 | 基于区块链的众包社区激励机制
- python-Python 3中字符串可以被改变吗?
- 爆火的Java面试题-kafka源码解析与实战豆瓣
- mfc mysql delete_MFC中简单的数据库文件操作(添加,修改,查找,删除)
- php公众获取用户信息,PHP--通过公众号获取用户微信信息
- Base64码常见操作(url链接文件转base64编码、本地文件转base64编码等)
- Microsoft Office 2019 正式版 安装记录
- 华南理工大学 电力电子技术(王兆安) 期末复习笔记2 第三章第四章
- FS7022双节锂电池8.4V保护IC电路图
- 网络准入系统usersafe守护企业内网安全
- 首款国产8K 50P小型化广播级摄像机惊喜亮相冬季冰雪体育盛会
- mysql 免费么,mysql收费吗
- 浅谈量子纠缠,易经,能量,世界(一)
- 录音文件下载_录音转文字别烦恼,收下这份锦囊,几种方法任你选!
热门文章
- boost::lexical_cast模块将创建一个to_long_double方法,将 Boost.Variant 的值转换为long double
- boost::hana::less_equal用法的测试程序
- boost::hana::flip用法的测试程序
- boost::graph模块实现包含平均测地线示例
- boost::boost::directed_graph用法的测试程序
- 宏BOOST_TEST_TRAIT_TRUE的用法
- Boost:bind绑定和或||的测试程序
- C++kruskals算法生成最小协议树(附完整源码)
- np.insert()
- android 蓝牙打印格式,Android蓝牙打印格式排版