Node.js轻松学(基础篇)笔记
#1 课程介绍与开发环境搭建
- terminal插件:可以在终端打开文件
#2 全局对象
- 浏览器中的全局对象:window,里面有方法console.log(),setTimeout()等
console.log(__dirname); //输出当前目录名
console.log(__filename); //输出文件名
// require exports
var time = 0;
setTimeout(() =>{
console.log("3 seconds have passed");
}, 3000);
var timer = setInterval(function() { //循环输出
time += 2;
console.log(time + " seconds have passed");
if (time > 5) {
clearInterval(timer);
}
}, 2000);
#3 回调函数
- 一般函数的定义
function sayHi() {
console.log('Hi');
}
var sayBye = function() {
console.log('Bye');
}
sayHi();
sayBye();
- 回调函数
function callFunction(fun) {
fun();
}
function callFunction(fun,param) {
fun(param);
}
callFunction(function(param){
//TODO
},param)
#4 模块
module.exports = func_name;
var func = require('./filename');
//暴露出一个对象
module.exports.func1 = func1_name;
module.exports.func2 = func2_name;
module.exports.func3 = func3_name;
var stuff = require('./filename');
stuff.func1();
module.exports = {
func1: func1_name;
func2: func2_name;
func3: func3_name;
}
var func1 = require('./count').pi;
#5 事件
- 用户点击触发事件
element.on('click',function() {
console.log('clicked');
})
- nodejs中触发事件
var events = require('events');
var util = require('util');
var myEmitter = new events.EventEmitter();
myEmitter.on('eventName',function(param) {
console.log(param)
})
myEmitter.emit('eventName',param);
var events = require('events');
var util = require('util'); //nodejs工具库
var Person = function(name) {
this.name = name
}
util.inherits(Person, events.EventEmitter); //继承类
var xiaoming = new Person('xiaoming');
var lili = new Person('lili');
var lucy = new Person('lucy');
var person = [xiaoming, lili, lucy];
person.forEach(function(person) //循环遍历
person.on('speak', function(message) { //事件绑定
console.log(person.name + " said: " + message);
})
})
xiaoming.emit('speak', 'hi'); //事件触发
lucy.emit('speak', 'I want a curry');
#6 读写文件(同步,异步)
- 同步:按代码顺序,从上到下依次执行,等上一个文件加载完才能加载下一个
- 异步:按加载顺序执行
- nodejs在执行JavaScript的时候是单线程的(!nodejs并不是单线程的
- nodejs维护了一个事件队列,读到事件时就会储存到事件队列中,当主线程空闲时会先向下执行,发起另一个线程去执行耗时的操作,执行成功后再通知主线程
- nodejs高性能,因为各步操作是可异步的
- 注意,异步的方法都要加回调函数
/*同步*/
//读文件
var fs = require('fs');
var readMe = fs.readFileSync("readMe","utf8"); //文件名,编码
//写文件
fs.writeFileSync("wtiteMe.txr",readMe); //文件名,文件内容
/*异步*/
var fs = require('fs');
var readMe = fs.readFile("readMe","utf8",function(err,data) { //文件名,编码,回调函数
console.log(data);
});
var writeMe = fs.writeFile('writeMe.txt',function() { //文件名,编码,回调函数
console.log("content");
});
#7 创建和删除目录
var fs = require('fs');
fs.unlink("writeMe.txt",function() { //异步删除
console.log("delete writeMe.txt file");
})
fs.mkdirSync('stuff'); //同步 创建目录
fs.mkdir('stuff',function() { //异步 复制文件
fs.readFile('readMe.txt','utf8',function(err,data) {
fs.writeFile('./stuff/writeMe.txt',data,function() {
console.log('copy successfully');
})
})
});
#8 流和管道
- 处理数据,将文件储存成一个个buffer来处理
- 提高性能
- 是一个事件的实例
var fs = require('fs');
var myReadStream = fs.createReadStream(_dirname + '/readMe.txt');
myReadStream.setEncoding("utf8"); //单独设置编码格式
var myReadStream = fs.createReadStream(__dirname + '/readMe.txt','utf8'); //直接设置编码格式
var myWriteStream = fs.createWriteStream(__dirname + '/writeMe.txt');
var data = ""
var writeData = "hello world";
myWriteStream.write(writeData);
myWriteStream.end();
myWriteStream.on('finish',function() { //设置一个监听方法,在结束时提醒
console.log('finished');
})
myReadStream.on('data',function(chunk) {
data += chunk;
myWriteStream(chunk);
})
myReadStream.on('end',function() {
console.log(data);
})
- 使用管道的方式复制粘贴文件
var fs = require('fs');
var myReadStream = fs.createReadStream(_dirname + '/readMe.txt');
myReadStream.setEncoding("utf8"); //单独设置编码格式
var myReadStream = fs.createReadStream(__dirname + '/readMe.txt','utf8'); //直接设置编码格式
var myWriteStream = fs.createWriteStream(__dirname + '/writeMe.txt');
myReadStream.pipe(myWriteStream);
// 解压
var crypto = require('crypto');
var fs = require('fs');
var zlib = require('zlib');
var password = new Buffer(process.env.PASS || 'password');
var decryptStream = crypto.createDecipher('aes-256-cbc', password);
var gzip = zlib.createGunzip();
var readStream = fs.createReadStream(__dirname + '/out.gz');
readStream // reads current file
.pipe(gzip) // uncompresses
.pipe(decryptStream) // decrypts
.pipe(process.stdout) // writes to terminal
.on('finish', function() { // finished
console.log('done');
});
// 压缩
var crypto = require('crypto');
var fs = require('fs');
var zlib = require('zlib');
var password = new Buffer(process.env.PASS || 'password');
var encryptStream = crypto.createCipher('aes-256-cbc', password);
var gzip = zlib.createGzip();
var readStream = fs.createReadStream(__dirname + "/readMe.txt"); // current file
var writeStream = fs.createWriteStream(__dirname + '/out.gz');
readStream // reads current file
.pipe(encryptStream) // encrypts
.pipe(gzip) // compresses
.pipe(writeStream) // writes to out file
.on('finish', function() { // all done
console.log('done');
});
ls | grep app
这个命令在Linux和mac才合适,或者Windows的Git bash
#9 web服务器part 1介绍
var http = require('http');
var onRequest = function(request,response) {
console.log('Request received')
response.writeHead(200,{'Content-Type':'text/plain'});
response.write('Hello from out application');
response.end();
}
var server = http.createServer(onRequest);
server.listen(3000,'127.0.0.1');
console.log('Server started on localhost port 3000');
#10 web服务器part 2 响应JSON
var http = require('http');
var onRequest = function(request,response) {
console.log('Request received')
response.writeHead(200,{'Content-Type':'application/json'});
var myObj = {
name:"name",
job:"programmer",
age:18
};
response.end(JSON.stringify(myObj));
}
var server = http.createServer(onRequest);
server.listen(3000,'127.0.0.1');
console.log('Server started on localhost port 3000');
JSON.parse(JSON.stringify(myObj)); //JSON的序列化和反序列化
#11 web服务器part 3 响应HTML页面
var http = require('http');
var onRequest = function(request,response) {
console.log('Request received')
response.writeHead(200,{'Content-Type':'text/html'});
var htmlFile ='<!DOCTYPE html>' +
'<html lang="en">' +
'<head>' +
'<meta charset="UTF-8">' +
'<meta name="viewport" content="width=device-width, '+
'initial-scale=1.0">' +
'<meta http-equiv="X-UA-Compatible" content="ie=edge">' +
'<title>Document</title>' +
'</head>' +
'<body>' +
'</body>' +
'</html>'
response.end(htmlFile);
}
var server = http.createServer(onRequest);
server.listen(3000,'127.0.0.1');
console.log('Server started on localhost port 3000');
- 利用流和管道响应HTML页面
var http = require('http');
var fs = require('fs');
var onRequest = function(request,response) {
console.log('Request received')
response.writeHead(200,{'Content-Type':'text/html'});
var myReadStream = fs.createReadStream(__dirname + '/index.html','utf8');
myReadStream.pipe(response);
}
var server = http.createServer(onRequest);
server.listen(3000,'127.0.0.1');
console.log('Server started on localhost port 3000');
#12 web服务器part 4 用模块化思想组织代码
//server.js
var http = require('http');
var fs = require('fs');
function startServer() {
var onRequest = function(request,response) {
console.log('Request received')
response.writeHead(200,{'Content-Type':'text/html'});
var myReadStream = fs.createReadStream(__dirname + '/index.html','utf8');
myReadStream.pipe(response);
}
var server = http.createServer(onRequest);
server.listen(3000,'127.0.0.1');
console.log('Server started on localhost port 3000');
}
exports.startServer = startServer;
//app.js
var server = require('./server');
server.startServer();
#13 web服务器 part 5 路由
var http = require('http');
var fs = require('fs');
function startServer() {
var onRequest = function(request, response) {
console.log('Request received ' + request.url);
if (request.url === '/' || request.url === '/home') {
response.writeHead(200, { 'Content-Type': 'text/html' });
fs.createReadStream(__dirname + '/index.html', 'utf8').pipe(response);
} else if (request.url === '/review') {
response.writeHead(200, { 'Content-Type': 'text/html' });
fs.createReadStream(__dirname + '/review.html', 'utf8').pipe(response);
} else if (request.url === '/api/v1/records') {
response.writeHead(200, { 'Content-Type': 'application/json' });
var jsonObj = {
name: "hfpp2012"
};
response.end(JSON.stringify(jsonObj));
} else {
response.writeHead(404, { 'Content-Type': 'text/html' });
fs.createReadStream(__dirname + '/404.html', 'utf8').pipe(response);
}
}
var server = http.createServer(onRequest);
server.listen(3000, '127.0.0.1');
console.log('Server started on localhost port 3000');
}
exports.startServer = startServer;
#14 web服务器 part 6 重构路由代码
//router.js
var fs = require('fs');
function route(handle,pathname,response){
console.log('Routing a request for ' + pathname);
if(typeof handle[pathname] === 'function') {
handle[pathname](response);
} else {
response.writeHead(200,{'Content-Type':'text/html'});
fs.createReadStream(__dirname + '/404.httml','utf8').pipe(response);
}
}
module.exports.route = route;
//handler.js
var fs = require('fs');
function home(response) {
response.writeHead(200,{'Content-Type':'text/html'});
fs.createReadStream(__dirname + '/index.httml','utf8').pipe(response);
}
function review(response) {
response.writeHead(200,{'Content-Type':'text/html'});
fs.createReadStream(__dirname + '/review.httml','utf8').pipe(response);
}
function api_records(response) {
response.writeHead(200, { 'Content-Type': 'application/json' });
var jsonObj = {
name: "hfpp2012"
};
response.end(JSON.stringify(jsonObj));
}
module.exports = {
home : home,
review : review,
api_records : api_records
}
//server.js
var http = require('http');
var fs = require('fs');
function startServer(route,handle) {
var onRequest = function(request, response) {
console.log('Request received ' + request.url);
route(handle,request.url,response);
}
var server = http.createServer(onRequest);
server.listen(3000, '127.0.0.1');
console.log('Server started on localhost port 3000');
}
module.exports.startServer = startServer;
//app.js
var server = require('./server');
var router = require('./router');
var handler = require('./handler');
var handle = {};
handle['/'] = handler.home ;
handle['/home'] = handler.home ;
handle['/review'] = handler.review ;
handle['/api/v1/records'] = handler.api_records ;
server.startServer(router.route,handle);
#15 web服务器 part 7 使用GET或POST请求发送数据
- GET方法:一般用于查询
- POST方法:一般用于提交
GET演示:
//server.js
var http = require('http');
var fs = require('fs');
var url = require('url');
function startServer(route,handle) {
var onRequest = function(request, response) {
var pathname = function(request.url).pathname;
console.log('Request received ' + request.url);
var params = url.parse(request.url,true).query; //取get传递的参数
route(handle,pathname,response,params);
}
var server = http.createServer(onRequest);
server.listen(3000, '127.0.0.1');
console.log('Server started on localhost port 3000');
}
module.exports.startServer = startServer;
//router.js
var fs = require('fs');
function route(handle,pathname,response,params){
console.log('Routing a request for ' + pathname);
if(typeof handle[pathname] === 'function') {
handle[pathname](response,params);
} else {
response.writeHead(200,{'Content-Type':'text/html'});
fs.createReadStream(__dirname + '/404.httml','utf8').pipe(response);
}
}
module.exports.route = route;
//handler.js
var fs = require('fs');
function home(response) {
response.writeHead(200,{'Content-Type':'text/html'});
fs.createReadStream(__dirname + '/index.httml','utf8').pipe(response);
}
function review(response) {
response.writeHead(200,{'Content-Type':'text/html'});
fs.createReadStream(__dirname + '/review.httml','utf8').pipe(response);
}
function api_records(response,params) {
response.writeHead(200, { 'Content-Type': 'application/json' });
response.end(JSON.stringify(params));
}
module.exports = {
home : home,
review : review,
api_records : api_records
}
POST演示:
//一个表单
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>hfpp2012</title>
</head>
<body>
<form action="/api/v1/records" method="post">
name: <input type="text" name="name" /> age: <input type="text" name="age" />
<input type="submit" value="Submit">
</form>
</body>
</html>
//server.js
var http = require('http');
var fs = require('fs');
var url = require('url');
var querystring = require('querystring');
function startServer(route,handle) {
var onRequest = function(request, response) {
var pathname = function(request.url).pathname;
console.log('Request received ' + request.url);
//var data = "";
var data = [];
request.on("error",function(err) {
console.error(err);
}).on("data",function(chunk) {
//data += chunk;
data.push(chunk);
}).on('end',function() {
if(request.method === "POST") {
if (data.length > 1e6) { //传送数据量过大时,取消该请求
request.connection.destory();
}
data = Buffer.concat(data).toString();
route(handle,pathname,response,parse(data));
} else {
var params = url.parse(request.url,true).query; //取get传递的参数
route(handle,pathname,response,params);
}
})
}
var server = http.createServer(onRequest);
server.listen(3000, '127.0.0.1');
console.log('Server started on localhost port 3000');
}
module.exports.startServer = startServer;
#16 包管理器 NPM
- 官网:https://www.npmjs.com/
- 框架:express
- 安装框架:
npm install express
- 安装单个包:
npm install -g webpack
- 安装很慢时:切换淘宝镜像
- yarn:另一包管理器
#17 package.json 文件
- dependencies,devDependencies:记录所有安装包的信息和版本
npm init
- scripts > start:入口文件;
npm run start
- 已有packa.json,安装包:
npm install
#18 nodemon
- 监控所有的文件,文件一旦改变,服务器就会自动重启
- 安装:
npm install -g nodemon
- 第一次运行:
nodemon xxx
or 在package.json > start:nodemon xxx