带你了解NodeJS常用API nodejs写api接口
qiyuwang 2024-10-31 15:52 17 浏览 0 评论
一、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的指向。
2.2 process 进程对象
process 包含了进程相关的属性和方法,Node 的 process 文档 中的内容特别多,列举几个常用方法。
Node 进程启动时传递的参数都在 process.arg数组中:
// process.js const {argv , execPath} = process argv.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()等。
三、基础 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/das path.join('user', 'local'), // user/local path.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:/sbin console.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.2 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.3 fs 文件系统
Node 文件模块通过require('fs)使用,所用方法都有同步和异步方法。
文件系统中的异步方法,第一个参数保留给异常,操作成功时参数值为null或undefined,最后一个参数就是回调函数。例如读取文件的fs.readFile()和写文件的fs.writeFile()示例如下:
const fs = require('fs') fs.readFile('./apiTest/fs.js', (err, data) => { if (err) throw err console.log('readFile done!!!') }) fs.writeFile('./apiTest/fs.txt', 'this is test file', { encoding: 'utf8' }, (err) => { if (err) throw err console.log('writeFile done!!!') })
小结
加油呢少年~
相关推荐
- 你真的会用Word画线吗?(word画线技巧)
-
【你真的会用Word画线吗?】①输入三个“=”回车,是一条双直线;②输入三个“”,回车,就是一条波浪线;③输入三个“”回车,就是一条虚线;④输入三个“-”,回车,就是一条细直线.....新技能get√...
- 「干货」Word技巧知识——进阶篇(2)
-
Hello,大家好,我是无拘无束的分享知识,每天跟大家分享点有用的知识,话不多说。感兴趣的朋友可以点赞、关注、收藏哦。1.将word文档中的硬回车全部消除从事来稿阅读、编辑的工作者,最头痛的事就是打...
- 办公室人员必备! Word快捷键大全(办公中常用的快捷键)
-
【Word里超简单的画线方法!】简历、总结里文字太多怎么办?用线条分隔!Word画线秘籍:①输三个"="回车,是一条双直线②输三个"~"回车,是一条波浪线③输三个"-"回车,就是一条细直线。(来源...
- Word笔记大全(详细步骤)(word怎么写笔记)
-
字处理一、文档的基本操作1.打开/新建2.快速新建ctrl+n3.利用模板创建文件--新建--选择模板officeplus4.保存5.保护文件--信息--保护文档--限制编辑--对话框:勾选每一项...
- 如何删除word文档空白页?(怎么删除word里的空白页?)
-
在日常办公或学习中,我们经常会遇到Word文档中出现空白页的情况,这不仅影响文档的美观,还可能造成打印浪费。下面,我将为大家详细介绍如何在Office和WPS中的Word里轻松删除这些恼人的空白页。...
- Win11学院:如何在Windows 11装机时禁用BitLocker磁盘加密
-
IT之家5月7日消息,微软计划在Windows1124H2装机过程默认启用BitLocker加密,对于用户来说有两方面的影响:其一是影响硬盘的性能,其二是用户如果没有解密密钥,可能...
- 办公小技巧:Word“安全模式”用通透
-
大家都知道Windows的安全模式。其实,Word也有安全模式。那么,Word的安全模式又是什么?何时使用这种模式?使用这种模式有何限制?当Word运行中遇到问题需要启用安全模式运行时,如何按照软件给...
- 段落结束敲回车,下一段格式变样了怎么处理#每天学习一点点
-
段落换行后的格式发生变化。段落结束敲回车键,下一段格式变样了怎么处理?大家有时候遇到文章敲回车键,在下一段打字之后会发现这一段的样子就会和之前的段落不一样,当然可以调整一下或者用格式刷刷一下,但是稍微...
- 硬回车、软回车等介绍(硬回车键和软回车键)
-
1.硬回车:硬回车占两个字节,在word中敲击Enter键即可输入硬回车,硬回车是真正的段落标记,在两个硬回车之间的文字自成一个段落。代码是^p(小写)。2.软回车:用Shift+Enter产...
- Word里超简单的画线方法!(word中如何画线条)
-
小厅分享【Word里超简单的画线方法!】简历、总结里文字太多怎么办?用线条分隔!Word画线秘籍:①输三个"="回车,是一条双直线②输三个"~"回车,是一条波浪线③输三个"-"回车,就是一条细直线...
- Word 如何更改图片、删除与删除背景,勾选图片等问题
-
如果插入到Word文档中的图片想另外换一张,更换方法有两种,一种是把原图删除另外插入一张,另一种是直接更换图片。Word2016提供了更改图片的功能,用此功能更换图片会自动把原图删除,就像...
- Word中批量删除空行(多种方案)(批量删除word中的空行)
-
如下图,在Word文档中存在大量空行(回车),为了文档整洁,需要批量取消这些回车;方法一Ctrl+h,在查找内容中输入”^p^p”,在替换为输入”^p”,单击全部替换即可(^符号在英文输入法下按Shi...
- Word文档如何取消自动编号?(word文档如何取消自动编号功能)
-
在word文档中,当我们编辑有序号的文本内容时,word会自动识别给文本编号,如果直接删除序号再按回车键,序号又会自动填充。但有时候我们并不需要它自动编号或不喜欢它的编号格式,如何才能取消word自动...
- 最全的Word知识点,抓紧时间收藏起来
-
Word知识点1.1word工作界面Word2010的窗口组成∶窗口分标题栏、菜单栏、常用工具栏、格式工具栏、标尺、编辑区滚动条、状态栏、任务窗格。1.标题栏∶显示所编辑的文档名和程序名称。单击标题...
- Word中的页眉横线就是删不掉?其实按下这个键,1秒就能去除
-
不知道大家在用Word的同时,有没有遇到过难删除的页眉横线呢?以前小编就是遇到这条横线,不得已将里面的文字复制到一个新的文档中,如今终于知道该怎样删除这条横线了,下面我们就来看看删除方法。一、删除页眉...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- navicat无法连接mysql服务器 (65)
- 下横线怎么打 (71)
- flash插件怎么安装 (60)
- lol体验服怎么进 (66)
- ae插件怎么安装 (62)
- yum卸载 (75)
- .key文件 (63)
- cad一打开就致命错误是怎么回事 (61)
- rpm文件怎么安装 (66)
- linux取消挂载 (81)
- ie代理配置错误 (61)
- ajax error (67)
- centos7 重启网络 (67)
- centos6下载 (58)
- mysql 外网访问权限 (69)
- centos查看内核版本 (61)
- ps错误16 (66)
- nodejs读取json文件 (64)
- centos7 1810 (59)
- 加载com加载项时运行错误 (67)
- php打乱数组顺序 (68)
- cad安装失败怎么解决 (58)
- 因文件头错误而不能打开怎么解决 (68)
- js判断字符串为空 (62)
- centos查看端口 (64)