Node.js 部分基础知识整理

回调函数

由于 node 是一个异步事件驱动的平台,所以在代码中我们经常需要使用回调函数。下面是回调函数应用的示例:

setTimeout(function(){
console.log('callback is called');
},2000);

我们传给 setTimeout 函数传入了一个匿名函数和一个调用时间 2000 (毫秒),运行程序后等待 2 秒,可以看到输出了”callback is called”。

标准回调函数

node.js 中回调函数格式是约定俗成的,它有两个参数,第一个参数为 err,第二个参数为 data,顾名思义,err 是错误信息,data 则是返回的数据,示例如下:

function(err,data){

}

os模块

提供操作系统的一些基本信息,它的一些常用方法如下:

var os = require("os");

var result = os.platform(); //查看操作系统平台
 //os.release(); 查看操作系统版本
 //os.type(); 查看操作系统名称
 //os.arch(); 查看操作系统CPU架构 
console.log(result);

进程管理

process 是一个全局内置对象,可以在代码中的任何位置访问此对象,这个对象代表我们的 node.js 代码宿主的操作系统进程对象。

使用 process 对象可以截获进程的异常、退出等事件,也可以获取进程的当前目录、环境变量、内存占用等信息,还可以执行进程退出、工作目录切换等操作。

process 对象的一些常用方法

process.cwd(); //查看应用程序当前目录
process.chdir("目录");//改变应用程序目录

stdout是标准输出流,它的作用就是将内容打印到输出设备上,console.log 就是封装了它

console.log = function(d){
process.stdout.write(d+'\n');
}

stderr是标准错误流,它是用来打印错误信息的,我们可以通过它来捕获错误信息:

process.stderr.write(输入内容);

stdin是进程的输入流,我们可以通过注册事件的方式来获取输入的内容,如下:

process.stdin.on('readable', function() {
 var chunk = process.stdin.read();
 if (chunk !== null) {
process.stdout.write('data: ' + chunk);
 }
});

示例中的 chunk 就是输入流中的内容。

exit需要在程序内杀死进程,退出程序,可以使用,示例如下:

process.exit(code);

参数 code 为退出后返回的代码,如果省略则默认返回0;

设置编码

在我们的输入输出的内容中有中文的时候,可能会乱码的问题,这是因为编码不同造成的,所以在这种情况下需要为流设置编码,如下示例:

process.stdin.setEncoding(编码); 
process.stdout.setEncoding(编码); 
process.stderr.setEncoding(编码);

文件I/O

写入文件

fs 模块提供 writeFile 函数,可以异步的将数据写入一个文件, 如果文件已经存在则会被替换。用法如下:

例:fs.writeFile(filename, data, callback)

var fs= require("fs");

fs.writeFile('test.txt', 'Hello node', function (err){
  if(err){
    throw err;
  }else{
    console.log('Saveed successfully');
  }

数据参数可以是 string 或者是 Buffer,编码格式参数可选,默认为”utf8”,回调函数只有一个参数err。

追加写入

fs 模块中有 appendFile 函数,它可以将新的内容追加到已有的文件中,如果文件不存在,则会创建一个新的文件。使用方法如下:

例:fs.appendFile(文件名,数据,编码,回调函数(err));

var fs= require("fs");

fs.appendFile('test.txt', 'data to append', function (err) {
   if (err) throw err;

    //数据被添加到文件的尾部
    console.log('The "data to append" was appended to file!'); 
});

编码格式默认为”utf8”,

是否存在

exists 函数可以检查一个文件是否存在。

例:fs.exists(文件,回调函数(exists));

exists 的回调函数只有一个参数,类型为布尔型,通过它来表示文件是否存在。

var fs= require("fs");

fs.exists('/etc/passwd', function (exists) {
  console.log(exists ? "存在" : "不存在!");
});

修改名称

rename 函数提供修改名称服务

var fs= require("fs");

fs.rename(旧文件,新文件,回调函数(err){
   if (err) throw err;
   console.log('Successful modification,');
});

移动文件

fs 没有专门移动文件的函数,但是我们可以通过 rename 函数来达到移动文件的目的,示例如下。

var fs = require('fs');

fs.rename(oldPath,newPath,function (err) {
   if (err) throw err;
   console.log('renamed complete');
});

读取文件

例:fs.readFile(文件,编码,回调函数);

var fs = require('fs');

fs.readFile(文件名, function (err, data) {
  if (err) throw err;
  console.log(data);
});

回调函数里面的 data ,就是读取的文件内容。

删除文件

例:fs.unlink(文件,回调函数(err));

var fs = require('fs');

fs.unlink(文件, function(err) {
  if (err) throw err;
  console.log('successfully deleted');
});

创建目录

fs.mkdir(路径,权限,回调函数(err));

参数

路径:新创建的目录。
权限:可选参数,只在 linux 下有效,表示目录的权限,默认为 0777,表示文件所有者、文件所有者所在的组的用户、所有用户,都有权限进行读、写、执行的操作。
回调函数:当发生错误时,错误信息会传递给回调函数的 err 参数。

删除目录

例:fs.rmdir(路径,回调函数(err));

var fs = require('fs');

fs.rmdir(path, function(err) {
  if (err) throw err;
  console.log('ok');
});

读取目录

readdir 函数可以读取到指定目录下所有的文件,示例如下:

var fs = require('fs');

fs.readdir(目录,回调函数(err,files));

回调函数 (callback) 接受两个参数 (err, files) 其中 files 是一个存储目录中所包含的文件名称的数组,数组中不包括 ‘.’ 和 ‘..’。

url 处理

parse

parse 函数的作用是解析 url,返回一个 json 格式的数组,请看如下示例:

var url = require('url');
url.parse('http://www.baidu.com');

运行结果:
{ protocol: ‘http:’,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: null,
query: null,
pathname: ‘www.baidu.com’,
path: ‘www.baidu.com’,
href: ‘http://www.baidu.com‘ }

条件解析

parse 函数的第二个参数是布尔类型,当参数为 true 时,会将查询条件也解析成 json 格式的对象。

var url = require('url');
url.parse('http://www.baidu.com?page=1',true);

运行结果:
{ protocol: ‘http:’,
slashes: true,
auth: null,
host: ‘www.baidu.com’,
port: null,
hostname: ‘www.baidu.com’,
hash: null,
search: ‘?page=1’,
query: { page: ‘1’ },
pathname: ‘/‘,
path: ‘/?page=1’,
href: ‘http://www.baidu.com/?page=1‘ }

解析主机

parse 函数的第三个参数也是布尔类型的,当参数为 true ,解析时会将 url 的”//“和第一个”/“之间的部分解析为主机名,示例如下:

var url = require('url');
url.parse('http://www.baidu.com/news',false,true);

运行结果:
{ protocol: ‘http:’,
slashes: true,
auth: null,
host: ‘www.baidu.com’,
port: null,
hostname: ‘www.baidu.com’,
hash: null,
search: null,
query: null,
pathname: ‘/news’,
path: ‘/news’,
href: ‘http://www.baidu.com/news‘ }
较之前面的示例,host 的内容不再是 null 了。

格式化

format 函数的作用与 parse 相反,它的参数是一个 JSON 对象,返回一个组装好的 url 地址,请看如下示例:

var url = require('url');
url.format({
protocol: 'http:',
hostname:'www.baidu.com',
port:'80',
pathname :'/news',
query:{page:1}
});

运行结果:
http://www.baidu.com/news?page=1
参数 JSON 对象的字段跟 parse 函数解析后返回的 JSON 字段一一对应。

resolve

esolve 函数的参数是两个路径,第一个路径是开始的路径或者说当前路径,第二个则是想要去往的路径,返回值是一个组装好的 url ,示例如下:

var url = require('url');

url.resolve('http://example.com/', '/one')  // 'http://example.com/one'
url.resolve('http://example.com/one', '/two') // 'http://example.com/two'

path 优化

本模块包含一套用于处理和转换文件路径的工具集,用于处理目录的对象,提高用户开发效率

格式化路径

normalize 函数将不符合规范的路径经过格式化转换为标准路径,解析路径中的.与..外,还能去掉多余的斜杠。

如下示例:

var path = require('path');  
var data = path.normalize('/path///normalize/hi/..');
console.log(data);

运行结果:
‘/path/normalize/‘

组合路径

join 函数将传入的多个路径拼接为标准路径并将其格式化,返回规范后的路径,避免手工拼接路径字符串的繁琐. 如下示例:

var path = require('path');
var data = path.join('///you', '/are', '//beautiful');
console.log(data);

运行结果:
‘/you/are/beautiful’

dirname

dirname 函数用来返回路径中的目录名. 如下示例:

var path = require('path');
var data = path.dirname('/foo/strong/cool/nice'); 
console.log(data);

运行结果:
‘/foo/strong/cool’

basename

basename 函数可返回路径中的最后一部分,并且可以对其进行条件排除. 如下示例:

例1:path.basename(‘路径字符串’);

例2:path.basename(‘路径字符串’, ‘[ext]’)<排除[ext]后缀字符串>;

var path = require('path');    
var data1 = path.basename('/foo/strong/basename/index.html');
var data2 = path.basename('/foo/strong/basename/index.html','.html');
console.log(data1 + ' "and" ' + data2);

运行结果:
‘index.html “and” index’

extname

extname 函数返回路径中文件的扩展名(以最后一个’.’开始,返回’.’以及’.’以后的所有字符串,如没有’.’,则返回空字符串). 如下示例:

var path = require('path');
var data = path.extname('index.html');
console.log(data);

运行结果:
‘.html’

字符串的转换

Query String 模块用于实现URL参数字符串与参数对象之间的互相转换,提供了”stringify”、”parse”等一些实用函数来针对字符串进行处理,通过序列化和反序列化,来更好的应对实际开发中的条件需求,对于逻辑的处理也提供了很好的帮助。

序列化

stringify 函数的作用就是序列化对象,也就是说将对象类型转换成一个字符串类型(默认的分割符(”&”)和分配符(”=”))。
例1:querystring.stringify(“对象”)

var querystring= require('querystring');
var result = querystring.stringify({foo:'bar',cool:['xux', 'yys']});
console.log(result);

运行结果:
foo=bar&cool=xux&cool=yys

多参数用法:
querystring.stringify(“对象”,”分隔符”,”分配符”)

var querystring = require('querystring');
var result = querystring.stringify({foo:'bar',cool:['xux', 'yys']},'*','$');
console.log(result);

运行结果:

'foo$bar*cool$xux*cool$yys'

反序列化

parse 函数,parse 函数的作用就是反序列化字符串(默认是由”=”、”&”拼接而成),转换得到一个对象类型。如下示例:

例1:querystring.parse(“字符串”)

var querystring = require('querystring');
var result = querystring.parse('foo=bar&cool=xux&cool=yys');
console.log(result);

运行结果:
{ foo: ‘bar’, cool: [‘xux’, ‘yys’]}

多参数用法:
querystring.parse(“字符串”,”分隔符”,”分配符”)

var querystring = require('querystring');
var result = querystring.parse('foo@bar$cool@xux$cool@yys','@','$');
console.log(result);

运行结果:
{ foo: ‘’, bar: ‘cool’, xux: ‘cool’, yys: ‘’ }

实用工具

util 模块呢,是一个 Node.js 核心模块,提供常用函数的集合,用于弥补核心 JavaScript 的一些功能过于精简的不足。并且还提供了一系列常用工具,用来对数据的输出和验证。

转换字符串

util.inspect(object,[showHidden],[depth],[colors]) 是一个将任意对象转换为字符串的函数,通常用于调试和错误输出。它至少接受一个参数 object ,即要转换的对象。使用语法如下:

var util = require('util');
var result = util.inspect(object);
console.log(result);

字符串格式化

format 函数根据第一个参数,返回一个格式化字符串,第一个参数是一个可包含零个或多个占位符的字符串。每一个占位符被替换为与其对应的转换后的值,支持的占位符有:”%s(字符串)”、”%d(数字<整型和浮点型>)”、”%j(JSON)”、”%(单独一个百分号则不作为一个参数)”。

1:如果占位符没有相对应的参数,占位符将不会被替换.如示例:

var util = require('util');
var result = util.format('%s:%s', 'foo');
console.log(result);

运行结果:
‘foo:%s’
2:如果有多个参数占位符,额外的参数将会调用 util.inspect() 转换为字符串。这些字符串被连接在一起,并且以空格分隔。如示例:

var util = require('util');
var result = util.format('%s:%s', 'foo', 'bar', 'baz');
console.log(result);

运行结果:
‘foo:bar baz’
3:如果第一个参数是一个非格式化字符串,则会把所有的参数转成字符串并以空格隔开拼接在一块,而且返回该字符串。如示例:

var util = require('util');
var result = util.format(1, 2, 3);
console.log(result);

运行结果:
‘1 2 3’

数组验证

isArray 函数可以判断对象是否为数组类型,是则返回 ture ,否则为 false 。语法如下:

var util = require('util');
var result = util.isArray(object);
console.log(result);

日期验证

isDate 函数可以判断对象是否为日期类型,是则返回 ture ,否则返回 false 。语法如下:

var util = require('util');
var result = util.isDate(object);
console.log(result);

正则验证

isRegExp 函数可以判断对象是否为正则类型,是则返回 ture,否则返回 false。语法如下:

var util = require('util');
var result = util.isRegExp(object);
console.log(result);

子进程

众所周知 node.js 是基于单线程模型架构,这样的设计可以带来高效的 CPU 利用率,但是无法却利用多个核心的 CPU,为了解决这个问题, node.js 提供了 child_process 模块,通过多进程来实现对多核 CPU 的利用。 child_process 模块提供了四个创建子进程的函数,分别是 spawn, exec, execFile 和fork。

创建子进程

pawn 函数用给定的命令发布一个子进程,只能运行指定的程序,参数需要在列表中给出。如下示例:

var child_process = require('child_process');
var child = child_process.spawn( command );
child.stdout.on('data', function(data) {
  console.log(data);
});

通过执行命令得到返回结果,我们就可以拿到标准输出流数据了。

exec

exec 也是一个创建子进程的函数,与 spawn 函数不同它可以直接接受一个回调函数作为参数,回调函数有三个参数,分别是 err, stdout , stderr,基本使用方法如下:

var child_process = require('child_process');
child_process.exec( command , function(err, stdout , stderr ) {
  console.log( stdout );
});

exec 函数可以直接接受一个回调函数作为参数,回调函数有三个参数,分别是 err, stdout,stderr,非常方便直接使用,

execFile

execFile 函数与 exec 函数类似,但 execFile 函数更显得精简,因为它可以直接执行所指定的文件,基本使用方法如下:

var child_process = require('child_process');
child_process.execFile( file , function(err, stdout , stderr ) {
  console.log( stdout );
});

execFile 与 spawn 的参数相似,也需要分别指定执行的命令和参数,但可以接受一个回调函数,与 exec 的回调函数相同。

fork

fork 函数可直接运行 Node.js 模块,所以可以直接通过指定模块路径而直接进行操作。使用方法如下:

var child_process = require('child_process');
child_process.fork( modulePath );

该方法是 spawn() 的特殊情景,用于派生 Node 进程。除了普通 ChildProcess 实例所具有的所有方法,所返回的对象还具有内建的通讯通道。