Node.js学习笔记

/**

 *Created by Monulix on 2018/5/10.

**/

//console.log("Good Bye,World");

//var fs = require('fs');

//fs.readFile('1.txt','utf-8',function(err,data){

//   if(err){

//       console.error(err);

//   }else{

//       console.log(data);

//   }                   //异步

//}); //何时事件队列进入回调函数;

//console.log('end dif');

//

//var data =fs.readFileSync('1.txt','utf-8');

//console.log(data);

//console.log('end syn'); //输出结果很像同步,难道该API曾被重构为异步;

//

///**javaScript 中的异步请求;**/

//function callbackfun(err,data){

//    if(err){

//       console.log(err);

//   }else{

//       console.log(data);

//   }

//}

//var fs1 = require('fs');

//fs1.readFile('1.txt','utf-8',callbackfun);

//console.log('javaScript end.'); //多个异步进行时,事件队列何时进入?

node.js所有的异步IO操作都会发出一个事件到事件队列;

//console.log('\n');

//var Event =require('events').EventEmitter;

//var eve = new Event();

//

//eve.on('some_event',function(){

//   console.log('\n10ss后发送使能信号,1slater,a tone');

//});

//setTimeout(function(){

//   eve.emit('some_event');

//   },3000);

for(var i = 0;i < 10000;++i){

   process.stdout.write('a');

   if((i % 27 == 0)||(i % 98 == 0)){

       process.stdout.write('\n');

   }

}

Node.js事件循环机制:

//   //程序的入口就是事件循环的第一个事件的回调函数(类似于main()),从事件循环开始,到事件循环结束;

///**回调函数执行时,可能会发出I/O请求或直接发射(emit)事件,执行完毕后

// 再返回事件循环,事件循环会检查事件队列中有没有未处理的事件,直到

// 程序结束;

// Node.js没有显式的事件循环,类似Ruby的EventMachine::run()的函数在

// Node.js中不存在,由libev库实现(被EventEmitter封装)。**/

//

require();覆盖

//var http1 = require('http');

http1.method();

//

//var http2 = require('http');  //无论调用多少次,实际对象只加载一次;

http2.method();

http1和http2是引用语义,指向同一个http对象,两者的输出是

相同的,因为后者会覆盖前者。

//

module.exports = Hello; instead theexports.Hello = Hello;

**外部引用该模块时,接口对象是Hello对象本身,而不是原先的

exports */

//

exports本身是普通的控对象,即{},专门用来声明接口,

本质上是通过它为模块闭包的内部建立了一个有限的访问接口。

不可以通过对export直接赋值代替对module.exports赋值。

exports实际上是一个和module.exports指向同一个对象的变量;

,但module不会,只能通过指定nodule.exports来改变访问接口。

//

"package.json"

npm install express 该包与python的pip和Ruby的gem不同;

npm默认安装到当前目录,其他两个是安装到全局;

//

npm i -g可以安装到全局;

全局模式安装的包require不能在上层目录寻找;但

通过npm -link的全局链接可以打破限制;

//

如 npm link express

./node_modules/express ->/usr/local/lib/node_modules/express

链接后可当做本地目录使用

//

npm link 不支持windows;与管理员权限有关;

命令行下单步调试;

//

node debug debug.js

远程调试, --debug = 1234,指定调试端口为1234;

node debug 127.0.0.1:5858

connecting... ok

...

//

核心模块

//

JS中的全局对象是window;Node.js中的全局对象是global;

所有全局变量(除了global本身)都是global对象的属性;

能直接访问到的对象基本欧式global对象的属性;

//

//

process.stdin.resume();  //初始输入流挂起

process.stdin.on('data',function(data){

   process.stdout.write('from console read:' +

   data.toString());

       if(data == null){

            process.stdout.write();

            return

       }

});

//

//

以下代码报callback不是一个函数;

//process.stdout.write("10010110".toString());

//process.nextTick(cback_func);//存在多个复杂任务时;

//

//function doSomething(args, cback_func){

//   sthComplicated(args);   //复杂过程;先1

//   process.nextTick(cback_func);   //立即回调,

//   //不用setTimeout(fn,0)代替process.nextTick(callback)

//   //效率低下

//}

//function cback_func(){

//

//}

// doSomething(function onEnd(){ //执行onEnd

//    compute();                //复杂过程2

// });

//

//function sthComplicated(args){

//   console.log("SthComplicated");

//}

//

//function compute(){

//   console.log("compute");

//}               //复杂过程2

 

//上述代码有错误,后面再查;

 

 

//new pro

//console.trace();

//util工具类;

 

//js的面向对象特性是基于原型的;

 

var util = require('util');

function Base() {

   this.name = 'base';

   this.base = 1991;

   this.sayHello = function() {

       console.log('Hello ' + this.name);

   };

}

Base.prototype.showName = function() {

   console.log(this.name);

};

function Sub() {

   this.name = 'sub';

}

util.inherits(Sub, Base);  //实现对象间原型继承;

var objBase = new Base();

objBase.showName();

objBase.sayHello();

console.log(objBase);

var objSub = new Sub();

objSub.showName();

//objSub.sayHello();  //类内部不被继承,原型方法才继承;与

//基于类的面向对象有差别;

console.log(objSub);

 

//

var util = require('util');

function per(name){

   this.name = name;

   this.toString = function(){

     return this.name;

   };

}

var obj = new per('12');

 

console.log('\n'+'person::');

console.log(util.inspect(obj));

console.log(util.inspect(obj,true));

 

//events模块;是node.js最重要的模块,没有之一。

//4.3.1 事件发射器 核心对象:events.EventEmitter;核心是事件发射器与事件监听器功能的封装;

console.log("\n事件与监听器***************");

var events = require('events');

var emitter = new events.EventEmitter();

 

emitter.on('Event', function(arg1,arg2){

   console.log('listener1', arg1, arg2); //emitter为事件someEvent注册了事件监听器1;

   var iRls = arg1 + arg2;

   console.log(iRls);

});

 

emitter.once('Event', function(arg1,arg2){

   console.log('listener2', arg1, arg2); //emitter为事件someEvent注册了事件监听器2;

   var iRls = arg1 * arg2;

   console.log(iRls);       //once为单次监听,触发后立即解除。

});

 

emitter.emit('Event',9,1991);

console.log("事件与监听器******************");

 

console.log('error事件********************');

 

/**

 *node.js的错误处理是通过事件和监听器机制来实现的;

 *@type {exports}

 */

var events = require('events');

var Emitter_GUI = newevents.EventEmitter();

Emitter_GUI.on('error',function(arg1,arg2){

   var error_rls = arg1/arg2;

   console.log(error_rls);

});

Emitter_GUI.emit('error',10,0);

console.log('error事件(异常处理???)********************\n');

 

//继承EventEmitter;

console.log('*************fileread*************');

var fs = require('fs');

fs.readFile('1.txt','utf-8',function(err,data){

  if(err){

      console.log(err);

   }else{

      console.log('\n'+data.toString());

   }

});

console.log('*************fileread.close*******\n');

 

 

console.log('*************文件同步读写sync readwrite*******\n');

var fs1 = require('fs');

try{

   fs1.readFileSync('0.txt');

}

catch(err){

   console.log(err);

}

console.log('*************compelte syncreadwrite*******\n');

 

console.log('*************fs.open*******\n');

   var fs = require('fs');

   fs.open('1.txt','r+',function(err, fd){

       if(err) {

           console.log(err);

           return;

       }

 

       var buf = new Buffer(8);   //缓冲区大小为八个字节

       fs.read(fd, buf, 0, 8, null,

           function(err, byteRead, buffer){

                if(err){

                    console.log(err);

                    return;

                }

       console.log('byteRead' + byteRead);

       console.log(buffer.toString());

   })

});

 

console.log('*************complete,fs.open*******\n');

 

 

console.log('*************http server andclient*******\n');

 

var http = require('http');

 

http.createServer(function(req,res){

   res.writeHead(200, {'Content-Type':'text/html'});

   res.write('<h1>ByeBye World</h1>');

   res.end('<p>qian zong niu bi</p>');

}).listen(12000);

 

console.log("http server listening atport 2000:");

 

console.log(">>>>>>>>>>>httpserverRequwst:>>>>>>>>>");

console.log(">>>>>>>>>>>获取get 请求内容:>>>>>>>>>");

var http = require('http');

var url = require('url');

var util = require('util');

 

http.createServer(function(req, res){

   res.writeHead(200,{'Content-Type': 'text/plain'});

   res.end(util.inspect(url.parse(req.url, true)));

}).listen(12001);

 

/**

 * 在浏览器中访问 http://127.0.0.1:12001/user?name=byvoid&email=byvoid@byvoid.com

 *结果如下:Url {

 protocol: null,

 slashes: null,

 auth: null,

 host: null,

 port: null,

 hostname: null,

 hash: null,

 search: '?name=byvoid&email=byvoid@byvoid.com',

 query:{ name: 'byvoid', email: 'byvoid@byvoid.com' },

 pathname: '/user',

 path:'/user?name=byvoid&email=byvoid@byvoid.com',

 href:'/user?name=byvoid&email=byvoid@byvoid.com' }

 */

 

console.log(">>>>>>>>>>>获取post 请求内容:>>>>>>>>>");

//httpserverrequestpost.js

var http = require('http');

var querystring = require('querystring');

var util = require('util');

http.createServer(function(req, res) {

   var post = '';

   req.on('data', function(chunk) {

       post += chunk;

   });

   req.on('end', function() {

       post = querystring.parse(post);

       res.end(util.inspect(post));

   });

}).listen(12002);

//不要在真正的生产应用中使用上面这种简单的方法来获取 POST 请

//求,因为它有严重的效率问题和安全问题,这只是一个帮助你理解的示例。

//http.ServerResponse;

 

console.log(">>>>>>>>>>>httpclient:>>>>>>>>>");

//http.request(options, callback);

 

//MVC模式:模型 视图控制器

/**

 *

 *@type {exports} 服务器向用户返回信息;

 */

console.log(">>>>>>>>>>>返回请求:>>>>>>>>>");

var http = require('http');

var querystring = require('querystring');

var server =http.createServer(function(req, res) {

    varpost = '';

   req.on('data', function(chunk) {

       post += chunk;

   });

   req.on('end', function() {

       post = querystring.parse(post);

       res.write(post.title);

       res.write(post.text);

       res.end();

   });

}).listen(3000);

//*********php方式*********//

//echo $_POST['title'];

//echo $_POST['text'];

 

console.log(">>>>>>>>>>>Expressframework:>>>>>>>>>");

//安装express

//$ npm install -g express

//express --help

//supervisor 实现监视代码修改和自动重启

//app.js是工程的入口;样式表style.css;

//路径匹配

 

console.log(">>>>>>>>>>>Expressframework cannot run:>>>>>>>>>");

//app.get('/usr/:username', function(req,res){

//   res.send('user: ' + req.params.username);

//});

 

//REST风格的路由规则

//route/index.js是路由文件,用于组织展示的内容;

/**

 *GET home page.

 */

exports.index = function(req, res){

   res.render('index', {title: 'Express' });

};

 

/**

 *module dependencies

 */

//MongoDB是对象数据库,JSON格式;

 

/**

* app.js

*/ //没有express对象,未添加依赖;

//var express = require('express'),

//   routes = require('./routes');

//

//var app = module.exports =express.createServer();

//app.configure();

 

/**

 * route/index.js 路由文件、Ctrl相当于控制器,用于组织展示内容;

 * index.ejs是模板文件,即routes/index中调用的模板;

 * layout.ejs所有模板继承自layout.ejs,可看做页面框架;

 */

 

/**

 *  浏览器——>路由控制器——>(模板引擎,静态文件,对象模型)

 *  模块加载机制

 *  异步编程模式下的控制流

 * Node.js应用部署

 * Node.js的劣势

 */

 

//fs,http,net,vm 加载优先级:.js, .json, .node;

//.json是json格式的文本;.node是编译好的C/C++代码;

 

//控制流

//循环陷阱:

var fs = require('fs');

var files = ['1.txt', '2.txt', '3.txt'];

 

/**

 *callback function在循环结束以后才能访问到外面的值;

 * 回调函数在此体现的淋漓尽致;

 */

for(var i = 0; i < files.length; ++i){

   fs.readFile(files[i], 'utf-8', function(err, data){

       console.log(i + '\t' + files[i] + '\n');

       // i 的值3次都为3;

       // file[i]越界报undifined;

       // 可见越界一般都报undifined就是未曾定义的对象;

       console.log(files[i] + ':' + data + '\n');

   });

}

 

//对以上过程进行更改,使得在合适的时间访问到相应的i;

var fs = require('fs');

var files = ['1.txt', '2.txt', '3.txt'];

 

for(var i = 0; i < files.length; ++i){

   (function(i){

   //利用js函数式编程特性,对回调函数进行闭包操作,

       fs.readFile(files[i], 'utf-8', function(err, data){

           console.log(i + '\t' + files[i] + '\n');

           console.log(files[i] + ':' + data + '\n');

       });

   })(i);

   console.log(i);

}

 

console.log("<<<<<<<<<forEachcallback function<<<<<<<<<<<<<");

//出于可读性考虑,使用ForEach来替代以上写法;

files.forEach(function(file){

   fs.readFile(file, 'utf-8', function(err, data) {

       console.log(file + ':' + data);  //forEach 隐式闭包;

   });

});

 

//控制流解耦模块;async;提供了async.series、async.parallel、async.waterfall

//等函数,代替函数嵌套使得程序变得清晰易读且易于维护,但必须遵守其约定的编程风格。

//stramlines和jscex实现了JS到JS的解释器,使用户可以用同步编程的

//模式写代码,但编译为异步的进行执行的中间代码;

//eventproxy深度封装事件发射器,采用完全基于事件松散耦合的方式来梳理

//控制流(以上都属于侵入式的手段);

 

//应用部署:不适合在产品环境中使用; node app.js

 

//日志功能:

//Express支持开发模式和产品模式:前者利于调试,后者利于部署。

 

//node.js适合逻辑简单但访问频繁的任务;不适合逻辑十分复杂的工作;

 

console.log("<<<<<<<<<<<<<由于环境崩溃,以下代码未全面测试,或有疏漏,敬请谅解指正<<<<<<<<<<");

console.log("<<<<<<<<<node.js的日志模块<<<<<<<<<<");

 

//使用产品模式运行服务器,只需设置NODE_ENV环境变量。通过NODE_ENV= productionnode app.js命令运行服务器

//可以看到 Express server listening on port 3000 in production mode;

//包含访问日志和错误日志功能;{访问日志记录用户对服务器的请求;含客户端IP地址,访问时间,访问

// 路径,服务器响应以及客户端代理字符串。错误日志则记录程序发生错误时的信息}。

 

//Express提供了一个访问日志中间件,只需要指定stream参数为一个输出流即可写入日志到文件;

//在app.js文件中,加入以下代码:

 

var fs = require('fs');

var accessLogfile =fs.createWriteStream('access.log', {flags: 'a'});

var errorLogfile =fs.createWriteStream('error.log', {flags: 'a'});

 

//app.configure函数第一行加入:app.use(express.logger({stream: accessLogfile}));

//错误日志需要单独实现错误响应:

app.configure('production', function() {

         app.error(function(err, reg, res, next) {

                  var meta = '[' + new Date() + ']' +req.url + '\n';

                           errorLogfile.write(meta + err.stack + '\n' );

                           next();

         });

});

//通过.app.error注册错误响应函数,

//throw new Error('An  error for test purposes.');     //以此来抛出自定义异常;

 

//cluster模块。cluster的功能是生成与当前进程相同的子进程,允许父进程和子进程之间共享端口;

//Node.js的另一个模块child_process也提供类似的进程生成功能,cluster允许跨进程端口复用;

 

//在外部调用app.js,需要禁止服务器自动启动。修改app.js,在app.listen(3000);前后加上判断语句;

 

if(! module.parent) {

         app.listen(3000);

         console.log("Expressserver", app.address().port, app.settings.env);

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值