【Node.JS】初入前端,学习node.js基本操作

一、Node.js 创建服务端应用

// 使用require指令加载模块
var http = require('http');

// 使用http.createServer()方法创建服务器
http.createServer(function (request, response) {
    
    

	// 通过request、response参数来接口和响应数据
    response.writeHead(200, {
    
    'Content-Type': 'text/plain'});
    response.end('Hello World\n');
    
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

在这里插入图片描述

二、npm 使用介绍

NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:

允许用户从NPM服务器下载别人编写的第三方包到本地使用。
允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。

npm可以分为全局安装和本地安装

# 本地安装
# 将安装包放在 ./node_modules 下(运行 npm 命令时所在的目录),
# 如果没有 node_modules 目录,会在当前执行 npm 命令的目录下生成 node_modules 目录。
# 可以通过 require() 来引入本地安装的包。
npm install express

# 全局安装
# 将安装包放在 /usr/local 下或者你 node 的安装目录。
# 可以直接在命令行里使用。
npm install express -g

三、Node.js 回调函数

Node所有API都支持回调函数,回调函数一般作为API的最后一个参数出现

阻塞代码实例

var fs = require("fs");	// 获取文件操作对象
var data = fs.readFileSync('input.txt');	//从input.txt文件中读取内容“菜鸟教程官网地址:www.runoob.com”

console.log(data.toString());	
console.log("程序执行结束");


/*
	菜鸟教程官网地址:www.runoob.com
	程序执行结束!
*/

非阻塞代码示例

var fs = require("fs");	// 获取文件操作对象

// 阻塞函数:还没读取完input.txt就先执行下面console代码,读取完了再执行function(err,data)函数
fs.readFile('input.txt', function (err, data) {
    
    
	/*
		如果在读取文件过程中发生错误,错误 err 对象就会输出错误信息。
		如果没发生错误,readFile 跳过 err 对象的输出,文件内容就通过回调函数输出。
	*/		
    if (err) return console.error(err);
    console.log(data.toString());
});

console.log("程序执行结束!");

/*
	程序执行结束!
	菜鸟教程官网地址:www.runoob.com
*/

四、Node.js 事件驱动程序

语法分析

// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();
// 绑定事件及事件的处理程序
eventEmitter.on('eventName', eventHandler);
// 触发事件
eventEmitter.emit('eventName');

具体示例

// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();
 
// 创建事件处理程序
var connectHandler = function connected() {
    
    
   console.log('连接成功。');
  
   // 触发 data_received 事件 
   eventEmitter.emit('data_received');
}
 
// 绑定 connection 事件处理程序
eventEmitter.on('connection', connectHandler);
 
// 使用匿名函数绑定 data_received 事件
eventEmitter.on('data_received', function(){
    
    
   console.log('数据接收成功。');
});
 
// 触发 connection 事件 
eventEmitter.emit('connection');
 
console.log("程序执行完毕。");

/*
	连接成功。
	数据接收成功。
	程序执行完毕。
*/

五、Node.js 事件监听器

事件监听器就是回调函数,event为事件绑定了回调函数,当事件发生时就会被回调函数监听到。

var events = require('events'); 
var emitter = new events.EventEmitter(); 

// event对象为someEvent绑定了监听器function,如果监听到了someEvent事件,就执行方法
emitter.on('someEvent', function(arg1, arg2) {
    
     
    console.log('listener1', arg1, arg2); 
}); 
// event对象为someEvent绑定了监听器function,如果监听到了someEvent事件,就执行方法
emitter.on('someEvent', function(arg1, arg2) {
    
     
    console.log('listener2', arg1, arg2); 
}); 
// 向event对象发送someEvent事件
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数'); 

/*
	listener1 arg1 参数 arg2 参数
	listener2 arg1 参数 arg2 参数
*/

六、特殊的error事件

EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到 异常的时候通常会触发 error 事件。

当 error 被触发时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并输出错误信息。

我们一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。例如:

var events = require('events'); 
var emitter = new events.EventEmitter(); 
emitter.emit('error'); 

运行时会显示以下错误:

node.js:201 
throw e; // process.nextTick error, or 'error' event on first tick 
^ 
Error: Uncaught, unspecified 'error' event. 
at EventEmitter.emit (events.js:50:15) 
at Object.<anonymous> (/home/byvoid/error.js:5:9) 
at Module._compile (module.js:441:26) 
at Object..js (module.js:459:10) 
at Module.load (module.js:348:31) 
at Function._load (module.js:308:12) 
at Array.0 (module.js:479:10) 
at EventEmitter._tickCallback (node.js:192:40) 

七、Node.js Buffer(缓冲区)

JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。

但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。

Buffer与字符编码
Buffer存储二进制数据,但是可以通过制定编码来输出数据

const buf = Buffer.from('runoob', 'ascii');

// 输出 72756e6f6f62
console.log(buf.toString('hex'));

// 输出 cnVub29i
console.log(buf.toString('base64'));

/*
	ascii - 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。
	utf8 - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。
	utf16le - 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。
	ucs2 - utf16le 的别名。
	base64 - Base64 编码。
	latin1 - 一种把 Buffer 编码成一字节编码的字符串的方式。
	binary - latin1 的别名。
	hex - 将每个字节编码为两个十六进制字符。
*/

创建Buffer类

// 创建一个长度为 10、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);

// 创建一个长度为 10、且用 0x1 填充的 Buffer。 
const buf2 = Buffer.alloc(10, 1);

// 创建一个长度为 10、且未初始化的 Buffer。
// 这个方法比调用 Buffer.alloc() 更快,
// 但返回的 Buffer 实例可能包含旧数据,
// 因此需要使用 fill() 或 write() 重写。
const buf3 = Buffer.allocUnsafe(10);

// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);

// 创建一个包含 UTF-8 字节 [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。
const buf5 = Buffer.from('tést');

// 创建一个包含 Latin-1 字节 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。
const buf6 = Buffer.from('tést', 'latin1');

/*
	Buffer.alloc(size[, fill[, encoding]]): 返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0
	Buffer.allocUnsafe(size): 返回一个指定大小的 Buffer 实例,但是它不会被初始化,所以它可能包含敏感的数据
	Buffer.allocUnsafeSlow(size)
	Buffer.from(array): 返回一个被 array 的值初始化的新的 Buffer 实例(传入的 array 的元素只能是数字,不然就会自动被 0 覆盖)
	Buffer.from(arrayBuffer[, byteOffset[, length]]): 返回一个新建的与给定的 ArrayBuffer 共享同一内存的 Buffer。
	Buffer.from(buffer): 复制传入的 Buffer 实例的数据,并返回一个新的 Buffer 实例
	Buffer.from(string[, encoding]): 返回一个被 string 的值初始化的新的 Buffer 实例
*/

写入缓冲区

/*
	string:写入缓冲区的字符串
	offset:开始写入的索引值,默认为0
	length:写入的字节数,默认为buffer.length
	encoding:使用的编码,默认为utf-8
	
	buf.write(string[, offset[, length]][, encoding])
*/

buf = Buffer.alloc(256);
len = buf.write("www.runoob.com");

console.log("写入字节数 : "+  len);	// 写入字节数 : 14

读取缓冲区

/*
	encoding - 使用的编码。默认为 'utf8' 。
	start - 指定开始读取的索引位置,默认为 0。
	end - 结束位置,默认为缓冲区的末尾。	
	
	buf.toString([encoding[, start[, end]]])
*/

buf = Buffer.alloc(26);
for (var i = 0 ; i < 26 ; i++) {
    
    
  buf[i] = i + 97;
}

console.log( buf.toString('ascii'));       // 输出: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5));   //使用 'ascii' 编码, 并输出: abcde
console.log( buf.toString('utf8',0,5));    // 使用 'utf8' 编码, 并输出: abcde
console.log( buf.toString(undefined,0,5)); // 使用默认的 'utf8' 编码, 并输出: abcde

/*
	abcdefghijklmnopqrstuvwxyz
	abcde
	abcde
	abcde
*/

缓冲区是有挺多方法的,这里只记录一些常用的方法。

八、输入输出流 Stream

输入流

var fs = require("fs");
var data = '';

// 创建可读流
var readerStream = fs.createReadStream('input.txt');

// 设置编码为 utf8。
readerStream.setEncoding('UTF8');

// 处理流事件 --> data, end, and error
readerStream.on('data', function(chunk) {
    
    
   data += chunk;
});

readerStream.on('end',function(){
    
    
   console.log(data);
});

readerStream.on('error', function(err){
    
    
   console.log(err.stack);
});

console.log("程序执行完毕");

/*
	程序执行完毕
	菜鸟教程官网地址:www.runoob.com
*/

输出流

var fs = require("fs");
var data = '菜鸟教程官网地址:www.runoob.com';

// 创建一个可以写入的流,写入到文件 output.txt 中
var writerStream = fs.createWriteStream('output.txt');

// 使用 utf8 编码写入数据
writerStream.write(data,'UTF8');

// 标记文件末尾
writerStream.end();

// 处理流事件 --> finish、error
writerStream.on('finish', function() {
    
    
    console.log("写入完成。");
});

writerStream.on('error', function(err){
    
    
   console.log(err.stack);
});

console.log("程序执行完毕");

/*
	以上程序会将 data 变量的数据写入到 output.txt 文件中。代码执行结果如下:
		程序执行完毕
		写入完成。
*/

九、Node.js 模块系统

导出模块

//hello.js 
function Hello() {
    
     
    var name; 
    this.setName = function(thyName) {
    
     
        name = thyName; 
    }; 
    this.sayHello = function() {
    
     
        console.log('Hello ' + name); 
    }; 
}; 
module.exports = Hello;	// 将函数Hello暴露出来

引入模块

//main.js 
var Hello = require('./hello'); 
hello = new Hello(); 
hello.setName('BYVoid'); 
hello.sayHello(); 

十、 Node.js 路由

在这里插入图片描述
server.js 文件代码

var http = require("http");
var url = require("url");
 
function start(route) {
    
    
  function onRequest(request, response) {
    
    
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");
 
    route(pathname);
 
    response.writeHead(200, {
    
    "Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }
 
  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}
 
exports.start = start;

router.js 文件代码

function route(pathname) {
    
    
  console.log("About to route a request for " + pathname);
}
 
exports.route = route;

index.js 文件代码

var server = require("./server");
var router = require("./router");
 
server.start(router.route);

运行结果

$ node index.js
Server has started.

在这里插入图片描述

十一、GET/POST请求

获取GET请求URL的参数

var http = require('http');
var url = require('url');
var util = require('util');
 
http.createServer(function(req, res){
    
    
    res.writeHead(200, {
    
    'Content-Type': 'text/plain'});
 
    // 解析 url 参数
    var params = url.parse(req.url, true).query;
    res.write("网站名:" + params.name);
    res.write("\n");
    res.write("网站 URL:" + params.url);
    res.end();
 
}).listen(3000);

在这里插入图片描述
获取POST请求内容

var http = require('http');
var querystring = require('querystring');
 
var postHTML = 
  '<html><head><meta charset="utf-8"><title>菜鸟教程 Node.js 实例</title></head>' +
  '<body>' +
  '<form method="post">' +
  '网站名: <input name="name"><br>' +
  '网站 URL: <input name="url"><br>' +
  '<input type="submit">' +
  '</form>' +
  '</body></html>';
 
http.createServer(function (req, res) {
    
    
  var body = "";
  req.on('data', function (chunk) {
    
    
    body += chunk;
  });
  req.on('end', function () {
    
    
    // 解析参数
    body = querystring.parse(body);
    // 设置响应头部信息及编码
    res.writeHead(200, {
    
    'Content-Type': 'text/html; charset=utf8'});
 
    if(body.name && body.url) {
    
     // 输出提交的数据
        res.write("网站名:" + body.name);
        res.write("<br>");
        res.write("网站 URL:" + body.url);
    } else {
    
      // 输出表单
        res.write(postHTML);
    }
    res.end();
  });
}).listen(3000);

在这里插入图片描述

十二、Node.js 搭建Web服务器

server.js

var http = require('http');
var fs = require('fs');
var url = require('url');
 
 
// 创建服务器
http.createServer( function (request, response) {
    
      
   // 解析请求,包括文件名
   var pathname = url.parse(request.url).pathname;
   
   // 输出请求的文件名
   console.log("Request for " + pathname + " received.");
   
   // 从文件系统中读取请求的文件内容
   fs.readFile(pathname.substr(1), function (err, data) {
    
    
      if (err) {
    
    
         console.log(err);
         // HTTP 状态码: 404 : NOT FOUND
         // Content Type: text/html
         response.writeHead(404, {
    
    'Content-Type': 'text/html'});
      }else{
    
                 
         // HTTP 状态码: 200 : OK
         // Content Type: text/html
         response.writeHead(200, {
    
    'Content-Type': 'text/html'});    
         
         // 响应文件内容
         response.write(data.toString());        
      }
      //  发送响应数据
      response.end();
   });   
}).listen(8080);
 
// 控制台会输出以下信息
console.log('Server running at http://127.0.0.1:8080/');

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
    <h1>我的第一个标题</h1>
    <p>我的第一个段落。</p>
</body>
</html>

接着我们在浏览器中打开地址:http://127.0.0.1:8080/index.html
在这里插入图片描述

十三、第一个Node.js Express 框架

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。
expressDemo.js

var express = require('express');
var app = express();

// 开启服务之后,如果访问到了/,就发生下面的函数
app.get('/', function (req, res) {
    
    
   res.send('Hello World');
})
 
// 监听器,监听到8081端口有动静就触发回调函数
var server = app.listen(8081, function () {
    
    
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("应用实例,访问地址为 http://%s:%s", host, port)
 
})

十四、Request对象和Response对象的具体介绍

Request 对象 - request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性。常见属性有:

req.app:当callback为外部文件时,用req.app访问express的实例
req.baseUrl:获取路由当前安装的URL路径
req.body / req.cookies:获得「请求主体」/ Cookies
req.fresh / req.stale:判断请求是否还「新鲜」
req.hostname / req.ip:获取主机名和IP地址
req.originalUrl:获取原始请求URL
req.params:获取路由的parameters
req.path:获取请求路径
req.protocol:获取协议类型
req.query:获取URL的查询参数串
req.route:获取当前匹配的路由
req.subdomains:获取子域名
req.accepts():检查可接受的请求的文档类型
req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一个可接受字符编码
req.get():获取指定的HTTP请求头
req.is():判断请求头Content-Type的MIME类型

Response 对象 - response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据。常见属性有:

res.app:同req.app一样
res.append():追加指定HTTP头
res.set()在res.append()后将重置之前设置的头
res.cookie(name,value [,option]):设置Cookie
opition: domain / expires / httpOnly / maxAge / path / secure / signed
res.clearCookie():清除Cookie
res.download():传送指定路径的文件
res.get():返回指定的HTTP头
res.json():传送JSON响应
res.jsonp():传送JSONP响应
res.location():只设置响应的Location HTTP头,不设置状态码或者close response
res.redirect():设置响应的Location HTTP头,并且设置状态码302
res.render(view,[locals],callback):渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
res.send():传送HTTP响应
res.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type
res.set():设置HTTP头,传入object可以一次设置多个头
res.status():设置HTTP状态码
res.type():设置Content-Type的MIME类型

十五、Node.js Web路由示例

var express = require('express');
var app = express();
 
//  主页输出 "Hello World"
app.get('/', function (req, res) {
    
    
   console.log("主页 GET 请求");
   res.send('Hello GET');
})
 
 
//  POST 请求
app.post('/', function (req, res) {
    
    
   console.log("主页 POST 请求");
   res.send('Hello POST');
})
 
//  /del_user 页面响应
app.get('/del_user', function (req, res) {
    
    
   console.log("/del_user 响应 DELETE 请求");
   res.send('删除页面');
})
 
//  /list_user 页面 GET 请求
app.get('/list_user', function (req, res) {
    
    
   console.log("/list_user GET 请求");
   res.send('用户列表页面');
})
 
// 对页面 abcd, abxcd, ab123cd, 等响应 GET 请求
app.get('/ab*cd', function(req, res) {
    
       
   console.log("/ab*cd GET 请求");
   res.send('正则匹配');
})
 
 
var server = app.listen(8081, function () {
    
    
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("应用实例,访问地址为 http://%s:%s", host, port)
 
})

接下来你可以尝试访问 http://127.0.0.1:8081 不同的地址,查看效果。
在这里插入图片描述

十六、Node.js 静态文件

Express 提供了内置的中间件 express.static 来设置静态文件如:图片, CSS, JavaScript 等

你可以使用 express.static 中间件来设置静态文件路径。例如,如果你将图片, CSS, JavaScript 文件放在 public 目录下
在这里插入图片描述

让我们再修改下 “Hello World” 应用添加处理静态文件的功能。

var express = require('express');
var app = express();
 
// 表示可以访问这里面的资源,如果不添加这一句,去访问public的资源会发生错误:Cannot GET /public/images/logo.png
app.use('/public', express.static('public'));
 
app.get('/', function (req, res) {
    
    
   res.send('Hello World');
})
 
var server = app.listen(8081, function () {
    
    
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("应用实例,访问地址为 http://%s:%s", host, port)
 
})

在浏览器中访问 http://127.0.0.1:8081/public/images/logo.png
在这里插入图片描述

十七、前端与后端的数据交互(HTML与Node.js)

GET请求
index.html代码

<html>
<body>
<form action="http://127.0.0.1:8081/process_get" method="GET">
First Name: <input type="text" name="first_name">  <br>
 
Last Name: <input type="text" name="last_name">
<input type="submit" value="Submit">
</form>
</body>
</html>

server.js代码

var express = require('express');
var app = express();
 
app.use('/public', express.static('public'));
 
app.get('/index.html', function (req, res) {
    
    
   res.sendFile( __dirname + "/" + "index.html" );
})
 
app.get('/process_get', function (req, res) {
    
    
 
   // 输出 JSON 格式
   var response = {
    
    
       "first_name":req.query.first_name,
       "last_name":req.query.last_name
   };
   console.log(response);
   res.end(JSON.stringify(response));
})
 
var server = app.listen(8081, function () {
    
    
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("应用实例,访问地址为 http://%s:%s", host, port)
 
})

浏览器访问 http://127.0.0.1:8081/index.html,向表单输入数据,并提交

在这里插入图片描述
POST请求
index.html代码

<html>
<body>
<form action="http://127.0.0.1:8081/process_post" method="POST">
First Name: <input type="text" name="first_name">  <br>
 
Last Name: <input type="text" name="last_name">
<input type="submit" value="Submit">
</form>
</body>
</html>

server.js代码

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
 
// 创建 application/x-www-form-urlencoded 编码解析
var urlencodedParser = bodyParser.urlencoded({
    
     extended: false })
 
app.use('/public', express.static('public'));
 
app.get('/index.html', function (req, res) {
    
    
   res.sendFile( __dirname + "/" + "index.html" );
})
 
app.post('/process_post', urlencodedParser, function (req, res) {
    
    
 
   // 输出 JSON 格式
   var response = {
    
    
       "first_name":req.body.first_name,
       "last_name":req.body.last_name
   };
   console.log(response);
   res.end(JSON.stringify(response));
})
 
var server = app.listen(8081, function () {
    
    
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("应用实例,访问地址为 http://%s:%s", host, port)
 
})

浏览器访问 http://127.0.0.1:8081/index.html,向表单输入数据,并提交

在这里插入图片描述

十八、Node.js 的RESTful API

举个例子吧,我们对一个数据库的CRUD,对应的接口和访问URL如下

@RequestMapping("/add/User")
public Boolean addUser()

@RequestMapping("/delete/User")
public Boolean deleteUser()

@RequestMapping("/update/User")
public Boolean updateUser()

@RequestMapping("/get/User")
public User getUser()

使用REST API,在HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

@RequestMapping("/User")			// 使用POST请求
public Boolean addUser()

@RequestMapping("/User")			// 使用DELET请求
public Boolean deleteUser()

@RequestMapping("/User")			// 使用PUT请求
public Boolean updateUser()

@RequestMapping("/get/User")		// 使用GET请求
public User getUser()

创建node.js代码实例
获取用户列表

var express = require('express');
var app = express();
var fs = require("fs");

app.get('/Users', function (req, res) {
    
    
   fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
    
    
       console.log( data );
       res.end( data );
   });
})

var server = app.listen(8081, function () {
    
    

  var host = server.address().address
  var port = server.address().port

  console.log("应用实例,访问地址为 http://%s:%s", host, port)

})

在浏览器中访问 http://127.0.0.1:8081/Users,结果如下所示:

{
    
    
   "user1" : {
    
    
      "name" : "mahesh",
      "password" : "password1",
      "profession" : "teacher",
      "id": 1
   },
   "user2" : {
    
    
      "name" : "suresh",
      "password" : "password2",
      "profession" : "librarian",
      "id": 2
   },
   "user3" : {
    
    
      "name" : "ramesh",
      "password" : "password3",
      "profession" : "clerk",
      "id": 3
   }
}

十九、Node.js 创建多进程

Node 提供了 child_process 模块来创建子进程,方法有:

  • exec - child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。
  • spawn - child_process.spawn 使用指定的命令行参数创建新进程。
  • fork - child_process.fork 是 spawn()的特殊形式,用于在子进程中运行的模块,如 fork(‘./son.js’) 相当于 spawn(‘node’, [‘./son.js’]) ,与spawn方法不同的是,fork会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。

exec()方法
child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。

console.log("进程 " + process.argv[2] + " 执行。" );
const fs = require('fs');
const child_process = require('child_process');
 
// 循环三次创建子线程执行任务
for(var i=0; i<3; i++) {
    
    
	// 子线程执行如下任务,然后将信息缓存起来,等待下面任务执行完毕
    var workerProcess = child_process.exec('node support.js '+i, function (error, stdout, stderr) {
    
    
        if (error) {
    
    
            console.log(error.stack);
            console.log('Error code: '+error.code);
            console.log('Signal received: '+error.signal);
        }
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
    });
 	// 子线程执行结束的时候,在控制台发出信息
    workerProcess.on('exit', function (code) {
    
    
        console.log('子进程已退出,退出码 '+code);
    });
}

执行以上代码,输出结果为:

$ node master.js 
子进程已退出,退出码 0
stdout: 进程 1 执行。

stderr: 
子进程已退出,退出码 0
stdout: 进程 0 执行。

stderr: 
子进程已退出,退出码 0
stdout: 进程 2 执行。

stderr: 

spawn() 方法
child_process.spawn 使用指定的命令行参数创建新进程
support.js 文件代码:

console.log("进程 " + process.argv[2] + " 执行。" );

master.js 文件代码:

const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
    
    
   var workerProcess = child_process.spawn('node', ['support.js', i]);
 
   workerProcess.stdout.on('data', function (data) {
    
    
      console.log('stdout: ' + data);
   });
 
   workerProcess.stderr.on('data', function (data) {
    
    
      console.log('stderr: ' + data);
   });
 
   workerProcess.on('close', function (code) {
    
    
      console.log('子进程已退出,退出码 '+code);
   });
}

执行以上代码,输出结果为:

$ node master.js stdout: 
进程 0 执行。
子进程已退出,退出码 0

stdout: 进程 1 执行。
子进程已退出,退出码 0

stdout: 进程 2 执行。
子进程已退出,退出码 0

fork() 方法
child_process.spawn 使用指定的命令行参数创建新进程
support.js 文件代码:

console.log("进程 " + process.argv[2] + " 执行。" );

master.js 文件代码:

const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
    
    
   var worker_process = child_process.fork("support.js", [i]);    
 
   worker_process.on('close', function (code) {
    
    
      console.log('子进程已退出,退出码 ' + code);
   });
}

执行以上代码,输出结果为:

$ node master.js 
进程 0 执行。
子进程已退出,退出码 0

进程 1 执行。
子进程已退出,退出码 0

进程 2 执行。
子进程已退出,退出码 0

二十、Node.js 对MySQL CRUD

查询数据

var mysql  = require('mysql');  
 
// 创建数据库对象
var connection = mysql.createConnection({
    
         
  host     : 'localhost',       
  user     : 'root',              
  password : '123456',       
  port: '3306',                   
  database: 'test' 
}); 
// 连接数据库
connection.connect();
 
// 创建SQL语句
var  sql = 'SELECT * FROM websites';
// 执行sql语句操作,并将结果放在result
connection.query(sql,function (err, result) {
    
    
        if(err){
    
    
          console.log('[SELECT ERROR] - ',err.message);
          return;
        }
 
       console.log('--------------------------SELECT----------------------------');
       console.log(result);
       console.log('------------------------------------------------------------\n\n');  
});
// 关闭数据库连接
connection.end();

插入数据

var mysql  = require('mysql');  
 
var connection = mysql.createConnection({
    
         
  host     : 'localhost',       
  user     : 'root',              
  password : '123456',       
  port: '3306',                   
  database: 'test' 
}); 
 
connection.connect();
 
var  addSql = 'INSERT INTO websites(Id,name,url,alexa,country) VALUES(0,?,?,?,?)';
var  addSqlParams = ['菜鸟工具', 'https://c.runoob.com','23453', 'CN'];
//增
connection.query(addSql,addSqlParams,function (err, result) {
    
    
        if(err){
    
    
         console.log('[INSERT ERROR] - ',err.message);
         return;
        }        
 
       console.log('--------------------------INSERT----------------------------');
       //console.log('INSERT ID:',result.insertId);        
       console.log('INSERT ID:',result);        
       console.log('-----------------------------------------------------------------\n\n');  
});
 
connection.end();

更新数据

var mysql  = require('mysql');  
 
var connection = mysql.createConnection({
    
         
  host     : 'localhost',       
  user     : 'root',              
  password : '123456',       
  port: '3306',                   
  database: 'test' 
}); 
 
connection.connect();
 
var modSql = 'UPDATE websites SET name = ?,url = ? WHERE Id = ?';
var modSqlParams = ['菜鸟移动站', 'https://m.runoob.com',6];
//改
connection.query(modSql,modSqlParams,function (err, result) {
    
    
   if(err){
    
    
         console.log('[UPDATE ERROR] - ',err.message);
         return;
   }        
  console.log('--------------------------UPDATE----------------------------');
  console.log('UPDATE affectedRows',result.affectedRows);
  console.log('-----------------------------------------------------------------\n\n');
});
 
connection.end();

删除数据

var mysql  = require('mysql');  
 
var connection = mysql.createConnection({
    
         
  host     : 'localhost',       
  user     : 'root',              
  password : '123456',       
  port: '3306',                   
  database: 'test' 
}); 
 
connection.connect();
 
var delSql = 'DELETE FROM websites where id=6';
//删
connection.query(delSql,function (err, result) {
    
    
        if(err){
    
    
          console.log('[DELETE ERROR] - ',err.message);
          return;
        }        
 
       console.log('--------------------------DELETE----------------------------');
       console.log('DELETE affectedRows',result.affectedRows);
       console.log('-----------------------------------------------------------------\n\n');  
});
 
connection.end();

猜你喜欢

转载自blog.csdn.net/m0_46638350/article/details/130269464