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 调用注册的事件

      

     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    LeetCode Array Easy 414. Third Maximum Number
    LeetCode Linked List Medium 2. Add Two Numbers
    LeetCode Array Easy 283. Move Zeroes
    LeetCode Array Easy 268. Missing Number
    LeetCode Array Easy 219. Contains Duplicate II
    LeetCode Array Easy 217. Contains Duplicate
    LeetCode Array Easy 189. Rotate Array
    LeetCode Array Easy169. Majority Element
    LeetCode Array Medium 11. Container With Most Water
    LeetCode Array Easy 167. Two Sum II
  • 原文地址:https://www.cnblogs.com/zhengweijie/p/7365053.html
Copyright © 2011-2022 走看看