Nodejs基础知识学习
1,当在某个文件夹下想要进入到命令行的时候,只需要按住shift键,然后右键点击进入命令行即可进入到当前路径下的命令行里面,而不需要单独在命令行里面一步一步cd进入到当前路径下。
2,在nodejs中,js文件里如果要定义类,因为js里面没有类,所以通过function来实现,在function中定义成员变量时只要使用this来定义成员变量即可,如,this.age = age;即可。
3,在nodejs中,要实现继承,可以通过“父类名.apply(this);”的方法来实现。
如:
User.js:
function User(id,age,name){
this.id = id;
this.age = age;
this.name = name;
this.enter = function(){
console.log(this.name+"进入图书馆"); //在控制台打印出来的
}
}
module.exports = User; //必须使用exports导出,在Teacher.js中才能使用require来请求;
Teacher.js:
var User = require('./User');
function Teacher(id,age,name){
User.apply(this,[id,age,name]);//继承父类的参数;
this.teach = function(res){
res.write(this.name+"讲课"); //在浏览器中打印出来的;
}//自己的方法
}
module.exports = Teacher;
4,使用正则表达式将path = “\login”中的 ‘\’去掉,
pathname= pathname.replace(/\//,' '); // ‘ \ ’ 是转义符,将/替换成 空的
获取路由:
var url = require('url');
var pathname = url.parse(request.url).pathname; //如果此时访问的页面地址为http://localhost:8000,则此时代表根目录,pathname为/ ;如果访问的地址为http://localhost:8000/login,则返回的pathname 值为 /login ,通过上面正则表达式的替换 ,得到 login;
5,闭包方法:就是在方法里再定义方法;
function getRecall(req,res){
function recall(data){
res.write(data);
res.end('');
}
return recall;
}
6,nodejs是单前程,分为同步和异步执行,多用异步,速度块:
//-----------n5_readfile-------------------------
var http = require('http');
var optfile = require('./models/optfile');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
if(request.url!=="/favicon.ico"){ //清除第2此访问
//optfile.readfile("./login.html"); //异步
optfile.readfileSync("./login.html"); //同步
response.end(ok);//不写则没有http协议尾
}
}).listen(8000);
console.log('Server running at http://127.0.0.1:8000/');
//-------------optfile.js-------------------------
var fs= require('fs'); //fs是自带的 读取文件的对象
module.exports={
readfile:function(path){ //异步执行
fs.readFile(path, function (err, data) {
if (err) {
console.log(err);
}else{
console.log(data.toString()); //打印数据的过程比较慢,先打印出别的,等数据读取完毕之后,再打印出来。
}
});
console.log("异步方法执行完毕"); //异步执行的结果的顺序为:异步方法执行完毕,主程序执行完毕,login.html里的内容,浏览器里打印的 还是 ok;
},
readfileSync:function(path){ //同步读取
var data = fs.readFileSync(path,'utf-8');
console.log(data);
console.log("同步方法执行完毕"); //后台打印结果的顺序为:login.html里的内容,同步方法执行完毕,主程序执行完毕,浏览器里打印的为 ok;
//return data;
}
}
如果想使用异步方法在客户端打印出所读取的文件里的数据,则不能简单的在readfile方法中修改参数,和添加res.write;如下:
//-------------optfile.js-------------------------
var fs= require('fs'); //fs是自带的 读取文件的对象
module.exports={
readfile:function(path,res){ //异步执行
fs.readFile(path, function (err, data) {
if (err) {
console.log(err);
}else{
console.log(data.toString()); //打印数据的过程比较慢,先打印出别的,等数据读取完毕之后,再打印出来。
res.write(data);
}
});
console.log("异步方法执行完毕"); //异步执行的结果的顺序为:异步方法执行完毕,主程序执行完毕,login.html里的内容,浏览器里打印的 还是 ok;
}
}
//-----------n5_readfile-------------------------
var http = require('http');
var optfile = require('./models/optfile');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
if(request.url!=="/favicon.ico"){ //清除第2此访问
console.log('访问');
response.write('hello,world');
optfile.readfile("./login.html",response); //这样写的话,执行到这里时,在打印数据的过程中,数据还没打完,就执行下面的打印结束,而在optfile文件中又执行到res.write这样会导致报错,"write after end ",所以需要利用闭包方法recall;
//optfile.readfileSync("./login.html");
response.end(ok);//不写则没有http协议尾
}
}).listen(8000);
console.log('Server running at http://127.0.0.1:8000/');
应该写成下面的调用闭包方法,回调函数的形式:
//-----------n5_readfile-------------------------
var http = require('http');
var optfile = require('./models/optfile');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
if(request.url!=="/favicon.ico"){ //清除第2此访问
function recall(data){
response.write(data);
response.end(ok);//不写则没有http协议尾
}
optfile.readfile("./login.html",recall); //原来的response参数 改成调用函数为参数
console.log("主程序执行完毕");
}
}).listen(8000);
console.log('Server running at http://127.0.0.1:8000/');
//-------------optfile.js-------------------------
var fs= require('fs'); //fs是自带的 读取文件的对象
module.exports={
readfile:function(path,recall){ //异步执行,因为在n5_readfile里,调用readfile时传入的参数是recall ,所以此处也必须定义成传入的是参数。
fs.readFile(path, function (err, data) {
if (err) {
console.log(err);
}else{
console.log(data.toString()); //打印数据的过程比较慢,先打印出别的,等数据读取完毕之后,再打印出来。
res.write(data);
}
});
console.log("异步方法执行完毕"); //异步执行的结果的顺序为:异步方法执行完毕,主程序执行完毕,login.html里的内容,浏览器里打印的 还是 ok;
}
}
7,通过路由来访问不同的页面;
--------------------n5_readfile.ts:
var http = require('http');
var url = require('url');
var router = require('./router'); //另外定义的router文件,内容就是通过使用闭包方法(方法里再嵌套方法的形式)
http.createSever ( function (request , response){
response.writeHead(200 , {'Content-Type':'text/html;charset = utf-8'}); //写协议的头;
if(request.url !== "/favicon.ico") { //favicon.ico 是浏览器默认的一次访问,使用这个的目的是清除第二次访问;
var pathname = url.parse(request.url).pathname;
pathname = pathname.replace(/\// , ' ');
router[pathname](request,response); //通过不同的pathname来调用router中的不同的方法来访问不同的页面
}
})
--------router.js:----------
var optfile = require('./models/optfile'); //注意 optfile就是optfile.js文件 引用的时候不用加.js
module.export = {
login : function(req, res) { //定义login和zhuce两个匿名函数;
function recall(data){
res.write(data);
res.end('');
}
optfile.readfile('./view/login.html' , recall); //此处传的是recall这种函数作为参数 ,可参见上面类似调用
},
zhuce : function(req, res){
function recall(data){
res.write(data);
res.end(''); //用来输出协议尾的,什么也不写则,在客户端(浏览器)输出内容后就没有协议尾;
}
optfile.readfile('./view/zhuce.html' , recall);
}
}
8,异步写文件:
在optfile.js文件中添加一个写文件的方法:
writefile:function(path , data , recall){ //异步方式
fs.writeFile(path , data , function (err){
if(err){
throw err;
}
console.log('It's saved');
recall('x写文件成功');
});
},
在n6_write.js中添加一个写文件的方法:
writefile:function(req , res){
function recall(data){
res.write(data);
res.end('');
}
optfile.writefile('./view/aaaa.txt' , '今天阳光正好' , recall); //写一个文件aaaa.txt , 内容为第二个参数,然后通过recall写在客户端浏览器上
}
8,在调试nodejs过程中,出现Cannot read property 'Symbol(asyncId)' of null 错误:
原因是,在关闭文件之后又进行读取操作了,如下:
n6_write.js:
var http = require('http');
var url = require('url');
var router = require('./rout');
http.createServer(function (request,response){
response.writeHead(200,{'Content-Type':'text/html:charset = utf-8'});
if(request.url != "/favicon.ico"){//清除第2次访问
var pathname = url.parse(request.url).pathname;
pathname = pathname.replace(/\//,'');
router[pathname](request,response);
//response.end(''); 如果有这句的话,则会报错Cannot read property 'Symbol(asyncId)' of null
}
}).listen(8000);
optfile.js:
var fs = require('fs');
module.exports = {
writefile:function(path,data,recall){
fs.writeFile(path,data,function(err){
if(err){
throw err;
}
console.log('It\'s saved');
recall('写文件成功');//再次调用recall,如果在n_write.js文件中没有注释掉response.end(),则会报上面的错
});
}
}
rout.js:
var optfile = require('./optfile');
module.exports = {
writefile:function(req,res){
function recall(data){
res.write(data);
res.end('hhhhh');
}
optfile.writefile('./aaa.txt','哈哈哈哈哈哈',recall);
}
}
10,路由,顾名思义,是指我们要针对不同的URL有不同的处理方式。例如处理/start的“业务逻辑”就应该和处理/upload的不同。
11,在C++或C#中,当我们谈到对象,指的是类或者结构体的实例。对象根据他们实例化的模板(就是所谓的类),会拥有不同的属性和方法。但在JavaScript里对象不是这个概念。在JavaScript中,对象就是一个键/值对的集合 -- 你可以把JavaScript的对象想象成一个键为字符串类型的字典。
但如果JavaScript的对象仅仅是键/值对的集合,它又怎么会拥有方法呢?好吧,这里的值可以是字符串、数字或者……函数!
12,我们需要的所有数据都会包含在request对象中,该对象作为onRequest()回调函数的第一个参数传递。但是为了解析这些数据,我们需要额外的Node.JS模块,它们分别是url和querystring模块。
url.parse(string).query | url.parse(string).pathname | | | | | ------ ------------------- http://localhost:8888/start?foo=bar&hello=world --- ----- | | | | querystring(string)["foo"] | | querystring(string)["hello"]
13,当读文本文件的时候,createServer方法里面写头协议的方法和读图片的时候头协议的方法时不同的,
读图片:response.writeHead(200,{'Content-Type':'image/jpeg'});
读文本:response.writeHead(200,{'Content-Type':'text/html:charset = utf-8'});
读图片的时候,readfile方法大同小异, 但是方法参数个数需增加一个,‘binary’二进制形式
14,阻塞是按顺序执行的,程序在等待时不可以干别的,非阻塞是不按顺序执行的,就是可以做些别的。所以如果需要处理回调函数的参数,我们就需要写在回调函数内。
但 阻塞和同步,非阻塞和异步并不是完全相同,有区别;