zoukankan      html  css  js  c++  java
  • Node,js笔记

    关于node的命令行

    node -e 'js文本'    解析一段js文本

    实时刷新:  npm install supervisor -g

          supervisor test.js

     

     

    关于node的模块化:

    node.js 不是一个框架,也不是一门语言,而是一个让javascriprt 运行在服务端的开发平台

    在Node环境中,一个.js文件就称之为一个模块(module)。这种模块加载机制被称为CommonJS规范

    在hello.js文件中:

    function greet(name) {
        console.log(s + ', ' + name + '!');
    }
    
    function getsame() {
      console.log('function')
    }
    module.exports = {    // 导出模块
      getsame,
      greet
    }

    在main.js文件中:

    var greet = require('./hello');   // 导入模块,相对路径
    
    greet.greet('小妹')    // 调用greet模块中的方法
    
    greet.getsame()

     

    关于node的基本模块:

    global :  全局对象,类似于window

    console : 输出对象

    process : 表示当前node的进程,可以通过它得到当前的工作目录、执行进程等

       process.cwd()   获得当前的工作目录

       process.chdir('路径')   切换当前工作目录

       process.on('exit' , function(){})   在node程序即将执行完退出时进行的回调

       process.nextTick()     在下一次事件循环中调用

    process.nextTick(function () {     // 在下一个事件执行完之后执行
        console.log('nextTick');
    });
    
    console.log(console)   // 执行完后执行process.nextTick()
    
    process.on('exit',function(code){    // 传入code 参数,表示执行结果
      console.log(code)
    })

     util :实用工具

      util.inherits(fun1, fun2):实现两个对象之间的原型继承,推荐使用ES6的 class extends 代替

    var util = require('util')
    
    function fun1 () {
      this.name = 'fun1'
    }
    
    function fun2 () {
      this.name = 'fun2'
    }
    
    fun1.prototype.showName = function() {   // 定义原型方法
      console.log(this.name)
    }
    
    util.inherits(fun1,fun2)    // 使用inherits 进行原型继承
    
    var test = new fun2();
    
    test.showName();   // 调用继承过来的方法

       

      util.inspect(obj, [showHidden], [depth], [colors])  将一个对象转化为字符串,接收四个参数,后面三个为可选参数    

       showHidden: 布尔值,如果为true, 将输出更多详细信息

      depth: Num值,表示标识最大的递归层数,即打印到第几层

      colors:布尔值,如果为true,则打印出来的数据具备对应文本颜色(只有视觉效果作用)

    var util = require('util')
    
    function obj () {
      this.name = 'object'
      this.fun = function() {
        console.log(this.name)
      }
    }
    
    console.log(util.inspect(obj,true,3,true))   
    // 输出 { [Function: obj]
    // [length]: 0,
    // [name]: 'obj',
    // [arguments]: null,
    // [caller]: null,
    // [prototype]: obj { [constructor]: [Circular] } }

    关于node的内置模块:

    读写文件:fs

     fs : 文件系统模块,负责读写文件     fs模块同时提供了异步和同步(Sync)的方法

    fs.readFile()     异步读取文件  ,传入文件路径、编码格式、回调函数
     
    fs.readFileSync()  同步读取文件,传入文件路径、编码格式     如果同步读取文件发生错误,则需要用try...catch捕获该错误
     
      var fs = require('fs');

    fs.readFile('test.txt','utf-8',function(err, data){ // 读取纯文本,传入文件路径、编码格式 if(err){ // 回调方法传入两个参数。err为失败信息,data为读取到的数据 console.log('读取出错了'+err) } else { console.log('读取的数据内容为:'+data) } }) fs.readFile('img.jpg',function(err, data){ // 读取二进制文件,传入文件路径,获得的data是一个Buffer对象 if(err){ console.log('读取出错了'+err) } else { console.log(data); // 输出<Buffer ff d8 ff e0 00 10 4a 46 49 ... > } }) var data = fs.readFileSync('test.txt','utf-8') // 同步读取文件,没有回调函数,直接返回结果 try { var data = fs.readFileSync('sample.txt', 'utf-8'); console.log(data); } catch (err) { // 出错了 }
     

    Buffer对象就是一个包含零个或任意个字节的数组(注意和Array不同)

    Buffer对象可以和String作转换,例如,把一个Buffer对象转换成String:

    var text = data.toString('utf-8');

    同时也可以把任意String转换成Buffer对象:

    var buf = new Buffer('这是一个utf-8编码格式的纯文本文件','utf-8');
    console.log(buf)   // 输出<Buffer e8 bf 99 e6 98 af e4 b8 80 ... >

    fs.writeFile()  异步将数据写入文件  ,依次传入三个参数,分别为文件名、写入的数据、回调函数。回调函数只有成功与否一个参数,err 为 null 时表示成功    该方法写入的数据会替换原本的数据内容

    fs.writeFileSync()  同步将数据写入文件

    传入的数据是String,默认按UTF-8编码写入文本文件,如果传入的参数是Buffer,则写入的是二进制文件

    var data = '这是新写入的数据内容'
    
    fs.writeFile('test.txt',data,function(err){    // 该方法会直接替换原本文件内的数据
      if(err){
        console.log('数据写入失败,错误为:'+err)
      } else {
        console.log('数据写入成功')
      }
    })
    
    fs.readFile('test.txt','utf-8',function(err, data){
      if(err){
        console.log(err)
      } else {
        console.log(data)  // 输出'这是新写入的数据内容'
      }
    })

    fs.stat(),获得文件的信息,它返回一个Stat对象,记录文件或目录的详细信息,如文件大小、创建时间等    stat()也有一个对应的同步函数statSync()

    fs.stat('test.txt', function (err, stat) {
        if (err) {
            console.log(err);
        } else {
            console.log('isFile: ' + stat.isFile());                    // 是否是文件:
            console.log('isDirectory: ' + stat.isDirectory());         // 是否是目录:
            if (stat.isFile()) {    
                console.log('size: ' + stat.size);                     // 文件大小:
                console.log('birth time: ' + stat.birthtime);          // 创建时间, Date对象:
                console.log('modified time: ' + stat.mtime);           // 修改时间, Date对象:
            }
        }
    });

    依次读写文件:stream : 流分为标准输入流(stdin) 和 标准输出流(stdout)   流的特点是数据是有序的,而且必须依次读取,或者依次写入 在Node.js中,流也是一个对象  配合fs 模块使用

    所有可以读取数据的流都继承自stream.Readable,所有可以写入的流都继承自stream.Writable   

    fs.createReadStream()     获得一个可读取的流   传入两个参数,第一个为文本路径,第二个为编码格式,使用on监听读取事件
                   data事件表示流的数据已经可以读取了,end事件表示这个流已经到末尾了,没有数据可以读取了,error事件表示出错
     
    var fs = require('fs');
    
    
    var rs = fs.createReadStream('test.txt','utf-8')   // 打开一个可读取的流
    
    rs.on('data', function(chunk){    //data表示已经在读取,该事件可能触发多次,每次传递的chunk是流的一部分数据。
      console.log('DATA:'+chunk)
    })
    
    
    rs.on('end', function(){
      console.log('读取结束')
    })
    
    rs.on('error',function(err){
      console.log('读取错误:'+err)
    })
    fs.createWriteStream()   获得一个可写入的流, 传入两个参数,第一个为文本路径,第二个为编码格式      该方法复制的数据会替换原本的数据内容
                 要以流的形式写入文件,只需要不断调用write()方法,最后以end()结束:
     
     
    var fs = require('fs');
    
    var wsl = fs.createWriteStream('test.txt','utf-8')    // 获得一个可写入的流
    
    wsl.write('这是使用流写入的数据');    // 调用write() 方法写入数据,可调用多次
    wsl.end();                        // 写入结束 以 end() 方法声明
    
    var ws2 = fs.createWriteStream('test.txt');      // 写入二进制数据
    ws2.write(new Buffer('使用流写入二进制数据', 'utf-8'));
    ws2.end();

    流的赋值:pipe  依次将一个流赋值给另一个流    pipe() 是读取流(Readable)的一个方法    其实就是复制    该方法写入的数据会替换原本的数据内容

    var fs = require('fs');
    
    var rs = fs.createReadStream('two.txt','utf-8')      // 获得一个可读取的流
    
    var ws = fs.createWriteStream('test.txt','utf-8')    // 获得一个可写入的流
    
    
    rs.pipe(ws)   // 将读取流rs的数据复制到写入流ws    ws原本的数据会被替换

    默认情况下,当Readable流的数据读取完毕,end事件触发后,将自动关闭Writable流。如果我们不希望自动关闭Writable流,需要传入参数:{end : false}

    readable.pipe(writable, { end: false });

     

     

    解析前端传递路径:url 模块    通过 url.parse() 将url字符串解析为一个对象

    url.parse(url,true)  接收两个参数,当后面为true时,query参数会以对象的形式打印出来
     
    url.parse().pathname      解析并获得请求文件地址
    'use strict';
    
    var url = require('url');
    
    console.log(url.parse('http://user:pass@host.com:8080/path/to/file?query=string#hash'));
    
    结果如下:
    
    Url {
      protocol: 'http:',
      slashes: true,
      auth: 'user:pass',
      host: 'host.com:8080',
      port: '8080',
      hostname: 'host.com',
      hash: '#hash',
      search: '?query=string',
      query: 'query=string',
      pathname: '/path/to/file',
      path: '/path/to/file?query=string',
      href: 'http://user:pass@host.com:8080/path/to/file?query=string#hash' }

    构造目录: path 模块   获得当前工作路径并对文件路径进行拼接

    path.resolve()     解析当前的路径,传入相对路径参数

    path.join()   将各个路径进行拼接    传入各个路径参数

    'use strict';
    
    var path = require('path');
    
    var workDir = path.resolve('.'); // 解析当前目录: 输出'/Users/zhengweijie/projects/tests/node'
    
    var filePath = path.join(workDir, 'test.txt');   // 可以有多个参数
    // 拼接路径   输出 /Users/zhengweijie/projects/tests/node/test.txt

     

     

    服务器:http 模块  

    通过http.createServer模块就可以创建node服务器

    request对象封装了HTTP请求,  即前端发起的数据请求信息

    response对象封装了HTTP响应,即后台需要返回的数据信息
     
    可在请求阶段定义各事件:
     
    server.on('connection',function(){
      console.log('连接请求中')
    })
    
    server.on('data',function(chunk){
      console.log('接收请求中,接收参数chunk')
    })
    
    server.on('end',function(chunk){
      console.log('接收请求完成时')
    })
    
    server.on('close',function(chunk){
      console.log('接收请求结束时')
    })
     
    简单的HTTP服务器程序实例:get方式
     
    'use strict';
    
    var http = require('http');  // 导入http模块:
    // 创建http server,并传入回调函数:  回调函数接收 request 和 response 对象,
    var server = http.createServer(function (request, response) { 
         //获得前端HTTP请求的请求方式method和请求地址url:
        console.log(request.method + ': ' + request.url);   
        // 后台进行响应,将HTTP响应200写入response, 同时设置Content-Type: text/html:   响应头
        response.writeHead(200, {'Content-Type': 'text/html'});
    
         // 将HTTP响应的HTML内容写入response: 即返回的数据内容   响应内容
        response.write('<h1>Hello world!</h1>');
    
        // 将HTTP响应的HTML内容写入response: 即返回的数据内容   响应尾
        response.end('<h1>end</h1>');
    });
    
    // 让服务器监听8080端口:   该端口所有的请求都会被创建的node服务监听到
    server.listen(8080);
    
    console.log('Server is running at http://127.0.0.1:8080/');
    HTTP服务器程序扩展实例:get方式
     
    'use strict'
    
    var http = require('http');  // 引入各个模块
    var fs = require('fs');
    var url = require('url');
    var path = require('path')
    
    var workDir = path.resolve(process.argv[2] ||'.');     // 获得当前的工作目录  
    
    var server = http.createServer(function(request, response){   // 创建HTTP服务
        console.log(request.method+':'+request.url)
        var pathName = url.parse(request.url).pathname           // 获得发起请求的URl路径
        var filePath = path.join(workDir, pathName)              // 将当前目录与请求的路径拼接,得到文件路劲
        console.log(filePath)
        fs.stat(filePath,function(err, stat){     // 使用该文件路径进行查询
            if(!err && stat.isFile()){              
                console.log('200 读取成功'+request.url)
                response.writeHead(200)
                fs.createReadStream(filePath).pipe(response)  // 直接使用流读取文件并赋值给 response 返回前端
            } else {
                console.log('404 文件不存在')
                response.writeHead(404)
                response.end('404 Not Found')
            }
        })
    })
    
    server.listen(5858);
    console.log('runing now')
     HTTP服务器程序扩展实例:post方式   使用 querystring
     
    'use strict';
    
    var http = require('http')
    var querystring = require('querystring')
    
    
    http.createServer(function(req,res){
      var post = ''
      req.on('data',function(chunk){
        post+=chunk
      })
    
      req.on('end',function(){
        post = querystring.parse(post)
        console.log('参数解析完成,返回name参数')
        res.end(post.name)
      })
    }).listen(3000)

    http模块提供了两个函数 http.requesthttp.get  , 功能是作为客户端向HTTP服务器 发起请求(类似于ajax)

    http.request(options, callback) 发起HTTP请求,需要接收两个参数,option是一个类数组对象,表示请求的参数,callback是请求的回调函数

      callback 传递一个参数,为http.ClientResponse的实例;http.request 返回一个http.ClientRequest的实例

    option常用参数:

      host : 请求网站的域名和IP地址

      port : 请求网站的端口,默认是80

      method : 请求方法,默认是get

      path :请求的相对于根的路径,默认是 ‘/’  QueryString应该包含在其中,例如 /search?query=test

      headers : 一个关联数组对象,为请求头的内容

       

    例子: (该例子执行报错)

    'use strict';
    
    var http = require('http')
    var querystring = require('querystring')
    
    // 启动服务
    http.createServer(function(req,res){
      var post = ''
      req.on('data',function(chunk){       // 解析post 参数
        post+=chunk
      })
    
      req.on('end',function(){
        post = querystring.parse(post)
        console.log('参数解析完成,返回name参数')
        res.end(post.name)
      })
    }).listen(3000)
    
    
    
    var contents = querystring.stringify({   // 声明 contents ,转为字符串
      name:'test',
      age: 21,
      address: 'guangzhou'
    });
    
    var options = {     // 声明请求参数
      host: 'localhost',
      path: '/',
      port: 3000,
      method: 'POST',
      headers: {
        'Content-Type':'application/x-www-form-urlecoded',
        'Content-length':contents.length
      }
    }
    // 客户端发起请求
    var req = http.request(options,function(res){
      res.setEncoding('utf-8')            // 声明读取编码,默认是 Buffer
      res.on('data',function(data){
        console.log('后台返回的数据:'+ data)
      })
    })
    
    req.write(contents)
    req.end()     // 必须调用,表示请求结

    http.get 是 http.request的简化版,区别在于http.get自动将请求方法设定为GET方式,同时不需要手动调用 req.end() 结束请求

    例子: (该例子执行报错)

    var http = require('http')
    var url = require('url')
    var util = require('util')
    
    // 启动服务
    http.createServer(function(req,res){
      console.log('请求到来,开始解析参数')
      var params = url.parse(req.url,true)
      console.log('解析完成')
      console.log(util.inspect(params));
      console.log('向客户端返回')
      res.end(params.query.name)
    }).listen(2000)
    
    
    // 客户端发起请求
    http.get({
      host: 'localhost',
      path: '/user?name=test&age=21',
      port: 2000
    },function(res){
      res.setEncoding('utf-8')
      res.on('data',function(data){
        console.log('返回的数据为:'+data)
      })
    })

    http.ClientRequest   该对象是由http.request或http.get返回产生的对象,表示一个已经产生而且正在进行的HTTP请求,它提供了response事件

    提供的函数:

      request.abort() 终止正在发送的请求

      request.setTimeout(timeout, callback)   设置请求超时时间,timeout为毫秒数,当请求超时后,触发回调函数

    http.ClientResponse   提供三个事件,data 、 end 和close , 分别在数据到达,传输结束和连接结束时触发,其中data事件传递一个参数chunk, 表示接受到的数据
    属性:表示请求的结果状态
      statusCode  HTTP状态码。如200, 404 , 500
      httpVersion : HTTP协议版本
      headers : HTTP请求头
      trailers : HTTP请求尾
     
    提供的函数:
      response.setEncoding([encoding])    设置读取编码格式,  默认为buffer
      response.pause()     暂停接收数据和发射事件,方便实现下载功能
      response.resume()    从暂停的状态中恢复
      
     

    事件模块 events   自定义各种事件

     
     如何自定义一个事件:EventEmitter    
    events 模块只提供了一个对象 EventEmitter   ,它的核心是事件的发射和监听(注册)功能的封装。EventEmitter的每个事件注册由一个事件或若干个参数组成。
       EventEmitter支持一次性注册若干个事件,当调用时会依次触发
     
     例子:
     
    var EventEmitter = require('events').EventEmitter   // 引入事件模块中的EventEmitter
    var event = new EventEmitter();                     // new声明一个EventEmitter 对象 event
    
    event.on('some_event',function(){                 // event.on 注册第一个自定义事件
      console.log('这是第一个自定义事件')
    })
    
    event.on('some_event',function(){                 // event.on 注册第二个自定义事件
      console.log('这是第二个自定义的事件')
    })
    
    setTimeout(function(){
      event.emit('some_event')           // 使用 emit 调用注册的事件,会依次触发定义的方法
    },1000)

     常用的APi:

    EventEmitter.on(eventName, function)    注册一个事件,接收事件名称和一个方法作为参数

    EventEmitter.emit(eventName, [arg1], [arg2]...)    调用(发射)注册的事件,接收事件名和事件传入参数(可选)作为参数

    EventEmitter.once(eventName, function)    类似于EventEmitter.on 注册事件,不过在调用一次后会自动解除,只能调用一次

    EventEmitter.removeListener(eventName, funName)    移除注册事件中的某个事件,接收注册的事件名和移除的事件名两个参数

    EventEmitter.removeAllListeners(eventName)    移除某个注册事件(整个移除),不传参数的请求下默认删除所有

    EventEmitter.once 例子:

    var EventEmitter = require('events').EventEmitter   // 引入事件模块中的EventEmitter
    var event = new EventEmitter();                     // new声明一个EventEmitter 对象 event
    
    
    event.once('some_event',function(){
      console.log('这是调用EventEmitter.once的回调')
    })  
    
    event.on('some_event',function(name){                 // event.on 注册第一个自定义事件
      console.log('这是第一个自定义事件')
      console.log(name)
    })
    
    
    setTimeout(function(){
      event.emit('some_event')           // 使用 emit 调用注册的事件,会依次触发定义的方法
      event.emit('some_event')          // 再次使用 emit 调用注册的事件,once定义的方法不再触发
    },1000)

    EventEmitter.removeListener:例子:

    var EventEmitter = require('events').EventEmitter   // 引入事件模块中的EventEmitter
    var event = new EventEmitter();                     // new声明一个EventEmitter 对象 event
    
    
    const fun1 = function(){
      console.log('这是第一个自定义事件')
    }
    const fun2 = function(name){                 // event.on 注册第一个自定义事件
      console.log('这是第二个自定义事件')
      console.log(name)
    }
    
    event.on('some_event',fun1)  
    
    event.on('some_event',fun2)
    
    event.removeListener('some_event',fun1)   // 使用removeListener 移除定义的事件
    
    event.emit('some_event')           // 使用 emit 调用注册的事件,会依次触发定义的方法,没有fun2

    EventEmitter.removeAllListeners 例子:

    var EventEmitter = require('events').EventEmitter   // 引入事件模块中的EventEmitter
    var event = new EventEmitter();                     // new声明一个EventEmitter 对象 event
    
    
    const fun1 = function(){
      console.log('这是第一个注册事件')
    }
    const fun2 = function(name){            
      console.log('这是第二个注册事件')
      console.log(name)
    }
    
    event.on('some_one',fun1)  
    
    event.on('some_two',fun2)
    
    event.removeAllListeners('some_one')   // 使用removeAllListeners 移除注册的事件,不传参数为删除全部
    
    event.emit('some_one')           // 使用 emit 调用注册的事件,不存在事件,已被移除
    
    event.emit('some_two')           // 使用 emit 调用注册的事件

      

     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    Delphi泛型系列(很不错)[转静候良机]
    数组的排序
    数据存储到流几种形式(数据流 TStream)
    [转]Delphi TStream详解
    Delphi匿名方法[转 静候良机]
    神一样的崇拜这个女人...打破了我对我们苦b程序员极限的了解
    sql server cte语法
    GdiPlus[49]: 图像(一) 概览
    GdiPlus[51]: 图像(三) 关于呈现
    GdiPlus[47]: IGPMatrix 矩阵(二)
  • 原文地址:https://www.cnblogs.com/zhengweijie/p/7365053.html
Copyright © 2011-2022 走看看