10.20 NODE

375 阅读6分钟

1. Node

1. node特性

  1. 异步触发
  2. 消息循环(事件队列实现)
  3. 单线程
  • 基于对象 模仿出面向对象特性(封装 继承 多态)
  • 有些模块不需手动加载
    • global
    • console
    • module
    • process
    • timer
    • exports

2. 安装

  • cmd node 全局安装

3. 执行

  1. REPL cmd下 退出.exit
  2. node name.js

4. 异步

  1. 先执行同步,再执行异步
  2. 触发异步条件
    • 当前线程空闲
    • 满足触发条件
  3. 判断异步 把异步处理方法发送到消息队列去排队
    for(var i=1;i<=3;i++){
        setTimeout(function(){
            console.log(i)
        })
    }
    console.log("end")

    //执行结果
    end
    4
    4
    4

2. 复习

1. 网页访问量计数方法

  1. 全局变量存在内存
  2. 文件存储 不同进程可以访问一个文件 会产生阻塞
  3. 数据库

2. 依赖包

  • npm install request安装在当前项目下node_modules
  • npm install request --savepackage.json dependices{}
  • npm install request --dev--savepackage.json dev-dependices{}
  • npm install -g request request全局安装
  • C:\Users\15477\AppData\Roaming\npm

3. http四大关键字

  • get
  • post
  • put
  • delete

4. 字符串转对象

  • node不支持stringfy和parse
    var str='{"name":"ccc","age":19}';
  1. 原生eval
  • 存在陷阱
    var obj=eval("("+str+")");
  1. parse
    var obj=JSON.parse(str);

5. 直接复制和引用赋值

    //地址改变
    var a=123;  //0x1a3b4c ---123
    var a=567;  //0x4a5d3a 
    
    //地址未改变
    var obj={
    	'a':123,
    }
    
    obj.a=567;

6. POST GET 区别

  • GET 数据都在utl上显示 数据不超过4096字节 1 byte=8bit
  • POST 数据传输安全 数据传输量大

7. npm install

  • 安装package.json中sependencies所有包
  • --save--dev 版本号也写入

8. require

  • 引入模块 原生模块,第三方模块,自定义模块
  • var http=require("http")原生模块 无需路径 不用npm install安装
  • var request=require("request")第三方模块 无需路径 npm install安装
  • var Module=require("./module.js")自定义模块 需要路径
  • var mm=require("./mm")自定义模块 需要路径mm.js/ mm文件夹下面的index.js

9. 基于对象

  • 继承
  • 封装
  • 多态

3. 包(network)

  • 包头(headers)最先执行
  • 包体(response)
  1. 如何识别html
  • content-type (传输类型)MIME头 409种
  1. node如何解决热更新问题
    1. supervisor(开发环境)
    • 下载npm install -g supervisor
    • supervisor app.js
    1. nodemon(开发环境)
    2. pm2(生产环境)

4. 三码一致

  1. 文件编码
  2. 浏览器解码
  3. 数据库编码

5. 原型链

  • Object.prototype{}
  • Function.prototype --- function(){}
  • Function.prototype.isPrototypeOf(Object) --- true
  • typeof(Object) --- function

6. node如何解决继承问题

  1. 父类的public变量和方法可以被子类访问
    • call()
    • apply()
    • bind()
  2. 子类的构造函数可以访问到父类的构造函数
  • call()配合inhrits()
    function MyStream(){
        //MyStream继承自events  call
    	events.EventEmitter.call(this);
    }
    
    //MyStream构造函数 要能访问到Events的构造函数
    util.inherits(MyStream,events.EventEmitter);

7. isPrototypeOf

  • 检查一个对象是否存在于另一个对象的原型链上
    Object.prototype.isPrototypeOf()
    
    Function.prototype.isPrototypeOf(Object)
    //true

8. node跨文件调用

1.prototype

    function Demo(){
    	var b=789;
    	//私有 类外不能调用
    	this.a=123;
    	this.bb=function(){
    		console.log(b);
    	}
    }
    //prototype 实例化不会实现
    Demo.prototype.write=function(){
    	console.log("writing");
    }

2. module.exports

  • 把类、对象、方法等暴露给外部
    //对象
    exports.bb=function(){
    	console.log("789");
    }
    //对象
    module.exports={
    	'a':123,
    	'bb':function(){
    		console.log(567);
    	}
    }   
    //方法
    exports={
    	'bb':function(){
    		console.log(890);
    	}
    }

3. exports 和 module.exports的区别

  • 模仿封装
  • require导出的内容是module.exports的指向的内存块内容,并不是exports的
  1. exports是指向module.exports的引用
  2. exports初始值{},module.exports初始值{}
  3. require()返回是module.exports而不是exports
    //公布方法
    function Person(){
      this.eat: function () {
        console.log('eat');
      },
      this.say: function () {
        console.log('say');
      }
    }
    
    
    //公布对象
    //1. 
    modle.exports = {
      'eat': function () {
        console.log('eat');
      },
      'say': function () {
        console.log('say');
      }
    }
    //2.
    exports.eat = function(){
      console.log('eat');
    }
    
    exports.say = function () {
      console.log('say');
    }
    3.
    exports.Person = {
      'eat': function () {
        console.log('eat');
      },
      'say': function () {
        console.log('say');
      }
    }
    //调用时Person.Person.say()

4. request

  • 原生模块 (console http fs dns) 无需路径 不用npm install安装
  • 第三方模块 (request) 无需路径
  • 自定义模块 需要路径
//引入mm文件夹下入口文件index.js
 var mm = "./mm";
 //引入Moudle.js 第三方模块
 var Moudle = ./Moudle.js"

9. 异步实例

    function Person(){
    	this.think=function(callback){
    		//thinking ~~~~~~
    		console.log("thinking ~~~~~~");
    		setTimeout(function(){
    			
    			callback();
    		},5000);
    
    	};
    
    	this.answer=function(){
    		console.log("I am answering other questions");
    	}
    }
    
    var person=new Person();
    person.think(function(){
    	console.log("thinking 5 seconds get the right answer");
    });
    
    person.answer();
    
    //I am answering other questions"
    //thinking ~~~~~~
    //thinking 5 seconds get the right answer

10. 返回一个网页

  1. 明确html文件的路径
  • __dirname取根路径(无需手动加载)
    var spath=__dirname+'/module/'+url.parse("index.html").pathname;
  • url.parse(req.url).pathname 网络路径
  1. 根据路径将文件读入到内存
    var indexPath=fs.readFileSync(spath,'utf-8');
  1. 把读入的内存的数据打成数据包发送给浏览器
    res.writeHead(200,{"Content-type":"text/html"});
    res.end(indexPath);

11. 预编译

  • 函数声明和变量声明会在预编译阶段被"提升"并且变量的提升是被最优先的提升的
    var aa = function(){
      console.log(123);
    }
    function aa(){
      console.log(456)
    }
    aa()
    //123

12. querystring

1. querystring.parse(str[, sep[, eq[, options]]])

'foo=bar&abc=xyz&abc=123' 被解析为: { foo: 'bar', abc: ['xyz', '123'] }

2. querystring.stringify(obj[, sep[, eq[, options]]])

    querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' });
    // 返回 'foo=bar&baz=qux&baz=quux&corge='
    
    querystring.stringify({ foo: 'bar', baz: 'qux' }, ';', ':');
    // 返回 'foo:bar;baz:qux'

1. 单项不可逆

  • md5()
  • rc6()
  • rsa()
  • sha1()
  • sha256()
    //md5()
    //npm install md5
    

crypto加密

  • crypto模块提供了加密功能,包括对 OpenSSL 的哈希、HMAC、加密、解密、签名、以及验证功能的一整套封装。

dgram数据报

dns域名服务器

  • dns.resolve4(解析hostname)
    var dns=require("dns");
    
    dns.resolve4("www.baidu.com",function(err,addresses){
    	if(err){
    		console.log(err);
    	}else{
    		console.log(addresses);
    	}
    })

events事件触发器

  • 所有能触发事件的对象都是 EventEmitter 类的实例

fs

  1. readFile
  • 文件系统
  • 读文件

1. 同步

    var data=fs.readFileSync("./demo.txt","utf-8");
    console.log(data);
    console.log("end");

2. 异步

  • fs.readFile(path[, options], callback)
    fs.readFile("./demo.txt","utf-8",function(err,data){
        if(err){
        console.log(err);
        }else{
        console.log(data);
        }
    });
    
    console.log("end");

http

  1. 发送数据包http get---发送http请求的方法并使用的是get http.get(url,callback)
    var http=require("http");
    var urls=["www.qq.com","www.baidu.com","www.sohu.com"];
    
    function fetchPage(url){
    	var start=new Date();
    	http.get({"host":url},function(){
    		console.log("Got respone from :"+url);
    		console.log("Request took:",new Date()-start,'ms');
    	});
    }
    
    for(var i=0;i<urls.length;i++){
    	fetchPage(urls[i]);
    }
  1. http.createServer([options][, requestListener])
  • options
    • IncomingMessage <http.IncomingMessage> 指定要使用的 IncomingMessage 类。
    • 用于扩展原始的 IncomingMessage。
    • 默认值: IncomingMessage。
    • ServerResponse <http.ServerResponse> 指定要使用的 ServerResponse 类。
    • 用于扩展原始 ServerResponse。
    • 默认值: ServerResponse
  • requestListener
  • 返回:<http.Server>
  • 返回新建的 http.Server 实例。
  • requestListener 是一个自动添加到 request 事件的函数。
  •     http.creatServer(function(req,res){
        	//1、获取文件的路径
        	var urlpath=__dirname+'/module/'+url.parse("index.html").pathname;
        	//2、要用fs的readFileSync 把文件读取到内存
        	var indexData=fs.readFileSync(urlpath,"utf-8");
        	//3、把内存数据打成数据包发送
        	res.writeHead(200,{"Content-type":"text/html"});
        	res.end(indexData);
        }).listen(3000);
    

    path

    1. path.join([...paths])
    • path.join() 方法使用平台特定的分隔符作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径。
        app.use(express.static(path.join(__dirname, 'public')));
    

    process

    • 自动加载
    1. process.env
        var port = normalizePort(process.env.PORT || '3000');
        //无端口号默认3000
    

    util实用工具

    1. util.inherits(constructor, superConstructor)
        function MyStream(){
            //MyStream继承自events  call
        	events.EventEmitter.call(this);
        }
        
        //MyStream构造函数 要能访问到Events的构造函数
        util.inherits(MyStream,events.EventEmitter);
    
    1. emitter.on(eventName, listener)
    • eventName | 事件名称
      • 事件 已定义事件+自定义事件
    • listener 回调函数