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

news2024/11/17 6:01:40

文章目录

  • 一、Node.js 创建服务端应用
  • 二、npm 使用介绍
  • 三、Node.js 回调函数
  • 四、Node.js 事件驱动程序
  • 五、Node.js 事件监听器
  • 六、特殊的error事件
  • 七、Node.js Buffer(缓冲区)
  • 八、输入输出流 Stream
  • 九、Node.js 模块系统
  • 十、 Node.js 路由
  • 十一、GET/POST请求
  • 十二、Node.js 搭建Web服务器
  • 十三、第一个Node.js Express 框架
  • 十四、Request对象和Response对象的具体介绍
  • 十五、Node.js Web路由示例
  • 十六、Node.js 静态文件
  • 十七、前端与后端的数据交互(HTML与Node.js)
  • 十八、Node.js 的RESTful API
  • 十九、Node.js 创建多进程
  • 二十、Node.js 对MySQL CRUD

一、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();

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

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

相关文章

Node 内置模块 【http模块】

文章目录 &#x1f31f;前言&#x1f31f;http模块&#x1f31f; 1.引入http模块&#x1f31f; 2.创建服务&#x1f31f; 3.添加头信息&#x1f31f; 4.搭建一个简单的服务器&#xff1a;&#x1f31f; 5.Request对象&#x1f31f; 6.Response对象&#x1f31f; 7.练习&#xf…

Mac 安装Java反编译工具JD-GUI

一、下载JD-GUI软件 1.首先到Github下载JD-GUI软件&#xff1a; github java-decompiler/jd-gui Public 选择jd-gui-osx-1.6.6.tar. 2.解压打开软件&#xff0c;但是提示错误&#xff1a; 3.确保本机已安装JDK. 4.如果确定已经安装了JDK海报这个这个错误&#xff0c;选中JD…

Ubuntu由于没有公钥,无法验证下列签名: NO_PUBKEY 79CDFD222CD3495A

执行update时&#xff0c;打印几行错误信息&#xff1a; sudo apt-get update命中:3 https://deb.termius.com squeeze InRelease 错误:3 https://deb.termius.com squeeze InRelease 由于没有公钥&#xff0c;无法验证下列签名&#xff1a; NO_PUBKEY 79CDFD222CD3495A W: 校…

海量数据的交互式分析工具Dremel

海量数据的交互式分析工具Dremel 产生背景数据模型两方面的技术支撑面向记录和面向列的存储嵌套模型的形式化定义 嵌套式的列存储数据的无损表示重复深度的定义定义深度的定义 高效的数据编码&#xff08;了解&#xff09;数据重组 查询语言与执行&#xff08;了解&#xff09;…

易点易动设备管理系统帮助水泥厂实现智能设备巡检

着工业4.0的不断发展&#xff0c;智能制造成为企业追求的目标。水泥厂作为基础建设的重要产业&#xff0c;其生产过程中设备的巡检维护显得尤为重要。本文介绍了易点易动设备管理系统如何帮助水泥厂实现智能设备巡检&#xff0c;提高设备管理效率&#xff0c;降低维修成本&…

卫浴工厂如何通过电子作业指导书系统实现信息化管理?

电子作业指导书系统可以帮助卫浴工厂实现信息化管理和智能化生产。电子作业指导书系统可以与其他管理系统和设备进行数据共享和信息交换&#xff0c;从而实现生产过程的智能化和自动化。 电子作业指导书系统是一种指导工人操作的电子化工具&#xff0c;可以将工艺流程、操作规范…

你的企业是不是需要一个wiki维基网页呢?

随着科技的不断发展和企业的不断壮大&#xff0c;企业内部的知识管理变得愈发重要。而wiki维基网页正是一种非常有效的知识管理工具&#xff0c;可以帮助企业更好地管理、分享和利用内部知识。 企业需要一个wiki维基网页的原因有哪些&#xff1f; 提高信息共享效率 在传统的…

WEB 工程路径专题--base 标签的使用和建议示意图

目录 WEB 工程路径专题 工程路径解决方案 解决方案&#xff1a;相对路径 2. 相对路径带来的问题举例 > 示意图 解决方案&#xff1a;base 标签 base 基本介绍 base 应用实例 a.html b.html Servlet03.java 练习 login.HTML user.html WEB 工程路径注意事项和细…

Storm proxies动态代理IP怎么挑选海外代理IP?

在选择海外代理IP时&#xff0c;需要考虑以下几个因素&#xff1a; 代理IP的稳定性和速度&#xff1a;代理IP的稳定性和速度是影响代理效果的重要因素。需要选择一个稳定、速度较快的代理IP&#xff0c;以确保能够快速、稳定地访问目标网站。代理IP的位置和数量&#xff1a;需要…

Node 内置模块 【fs模块】

文章目录 &#x1f31f;前言&#x1f31f;fs模块&#x1f31f; 使用fs模块&#x1f31f; 异步编程和同步编程&#x1f31f; 异步编程&#x1f31f; 同步编程 &#x1f31f;常用操作&#x1f31f; 文件操作&#x1f31f; readFile异步读取文件&#x1f31f; readFileSync同步读取…

OPencv图像读取_显示_保存

OPencv图像读取_显示_保存 一.OpenCV图像处理系统组成&#xff1a; OpenCV 主体分为五个模块&#xff0c;分别为CV、MLL,HighGUI、CXCORE&#xff0c;CVAux。OpenCV 的 CV 模块包含基本的图像处理函数和高级的计算机视觉算法。ML 是机器学习库&#xff0c;包含一些基于统计的…

哪个品牌的洗地机更好用?热门洗地机盘点

洗地机没有使用过之前一直怀疑是不是智商税&#xff0c;等到后面体验过之后&#xff0c;发现是真的香。因为不可否认的是&#xff0c;洗地机的清洁力还是不错的。不仅能够快速清洁干净地面&#xff0c;大大的节省了我们的清洁用时&#xff0c;操作起来也省心省力。作为一个洗地…

智驾系统的设计瓶颈之:电源管理设计中的功能安全和状态机

摘要&#xff1a; 本文从智驾系统电源管理设计的角度详细分析了整个系统的电源设计方式。 在整车电源管理中&#xff0c;IC 需要将多轨降压、升压和 LDO 稳压功能与每个电轨的参数&#xff0c;以及与其他电轨间交互的复杂可配置能力整合在一起。对于智驾系统设计人员而言&…

Python中类的属性、多继承、自省机制中的__mro__、__dict__ 和dir介绍

一、通过类名修改属性和通过类的实例去修改类的属性的区别 在 Python 中&#xff0c;类的属性可以通过类名或类的实例访问和修改。但是&#xff0c;通过类名修改属性和通过类的实例修改属性之间有一些区别。通过类名修改属性实际上是修改类的属性。这意味着如果你修改了类的属性…

GrapeCity Documents for Word 6.1.0

GrapeCity Documents for Word 6.1.0 改进了聚合函数中多个表达式的使用。 特征 GcWord 模板&#xff1a; 现在可以使用表达式作为聚合函数的参数。表达式可以在函数中使用常量、聚合或两个集合。现在可以进行以下计算&#xff1a; 使用常量 - {{ calc Sum(2 ds.value)}}。在聚…

5.MapReduce概述

ps.实际生产环境中并不会使用mapReduce,而是spark和flink,但是它可以建立分布式的思想。 1.MapReduce框架 2.mapReduce小项目练习 ps.基本流程:一般都是在代码层面引入hadoop依赖,然后在windows环境下进行代码编写测试,没有问题的话,把代码打包成jar包,然后拖入xShell,利用…

基于单片机的电路特性测试仪的设计

摘 要 当今社会科技的飞速发展&#xff0c;智能和便捷已经成为人们的日常诉求。现在放大电路在使用过程中经常出现故障&#xff0c;并且需要测试电路数据&#xff0c;但是大多数是手动进行测试&#xff0c;一定程度上影响了工作效率。 为了测量数据更安全更便捷&#xff0c;针…

YOLOv8 更换主干网络之 GhostNetV2

《GhostNetV2:Enhance Cheap Operation with Long-Range Attention》 轻量级卷积神经网络(CNN)是专门为在移动设备上具有更快推理速度的应用而设计的。卷积操作只能捕捉窗口区域内的局部信息,这防止了性能的进一步提高。将自注意力引入卷积可以很好地捕捉全局信息,但这将大…

MySQL-----表的增删查改

文章目录 前言一、create1. 单行数据 全列插入2. 多行数据 指定列插入3. 插入冲突否则更新4. 替换 二、retrieve1. select列1.1 全列查询1.2 指定列查询1.3 查询字段为表达式1.4 为查询结果指定别名1.5 结果去重 2. where条件2.1 英语不及格的同学及英语成绩 ( < 60 )2.2 …

Google浏览器翻译无法正常使用解决

1.查找可用服务器地址 按WinR键打开运行→输入cmd回车&#xff0c;打开命令提示符→输入ping google.cn 回车。记录一下下图红框里的ip地址&#xff0c;一会要用到 最近自己ping出来的ip可能不能用了&#xff0c;可以尝试用下面的ip 142.251.163.90 142.250.113.90 142.251.…