zoukankan      html  css  js  c++  java
  • nodejs知识结构

    一、回调函数

    node 的所有API都支持回调函数。阻塞是按顺序执行的,而非阻塞是不需要按顺序的,所以如果需要处理回调函数的参数,就需要些在函数内。

    Node.js 异步编程的直接体现就是回调。异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。

    • node 是单进程单线程应用程序,单因为 V8 引擎提供的异步执行回调接口,可以处理大量的并发,性能很高。
    • 几乎所有的事件机制都是观察者模式实现;
    • 每一个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数;
    • 执行异步操作的函数将回调函数作为最后一个参数,回调函数接收错误对象作为第一个参数

    二、事件驱动

    • web server 可以一直接受请求而不等待任何读写操作:称之为非阻塞IO或者事件驱动IO;
    • 在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数;
    • nodejs 所有异步io操作在完成时都会发送一个事件到事件队列
    • 只要是支持事件响应的核心模块都是 EventEmiiter 的子类
    var events = require("events");
    var eventEmitter = new events.EventEmitter();
    
    // 定义事件观察者、监听器、或者叫处理器
    var eventHandler = function handler(){
        console.log("handle event")
    }
    
    // 事件注册
    var eventEmitter.on("demo", eventHandler);
    
    // 事件发布
    var eventEmitter.emit("demo")
    

     三、buffer

    buffer类用来创建一个专门存放二进制数据的缓冲区,buffer类似于一个整数数组。

    3.1、支持的字符编码

    • ascii
    • utf8
    • uft16le
    • ucs2
    • base64
    • latin1
    • binary
    • hex : 一个字节(8 bit)编码为两个十六进制字符

    3.2、创建Buffer类

    • Buffer.alloc
    • Buffer.allocUnsafe
    • Buffer.allocUnfaseSlow
    • Buffer.from

    3.3、写缓冲区

    • buf.write

    3.4、读缓冲区

    • buf.toString
    • buf.toJSON()

    四、Stream

    • http 服务器发起请求的 request 对象就是一个 Stream,stdout 也是一个Stream
    • Stream 对象都是 EventEmitter 实例,常用事件:data,end,error,finish
    • 四种类型: Readable,Writable,Duplex,Transform
    • 管道流:从一个流中获取数据并将数据传递到另外一个流中;
    • 链式流:

    五、模块系统

    • 模块是为了更好的代码服用,文件和模块一一对应,可以是 js 代码,json,或者 c/c++ 扩展;

    • 模块创建的两种方式: exports, module.exports

    exports.world = function () {
        console.log("hello world!")
    }
    

      

    function Hello() { 
        var name; 
        this.setName = function(thyName) { 
            name = thyName; 
        }; 
        this.sayHello = function() { 
            console.log('Hello ' + name); 
        }; 
    }; 
    module.exports = Hello;
    

      使用模块:require

    var hello = require('hello');
    hello.world()
    

      

    var Hello = require('./hello'); 
    hello = new Hello(); 
    hello.setName('BYVoid'); 
    hello.sayHello(); 
    

      

    • 模块类型:原生模块(http, fs, path, os…), 相对路径文件模块,绝对路径文件模块,文件模块
    • 模块加载顺序: 原生模块 > 文件模块, 优先从缓存中加载,缓存中没有则从文件加载,并保存到缓存中。

    六、函数

    • js 中的函数是第一类对象,可以作为参数或返回值
    • 匿名函数与lambda表达式:以更简洁的形式进行函数对象的传递
    function hello(say) {
        say();
    }
    
    hello(function(){
        console.log("hello node!");
    })
    
    hello(()=> console.log("hello lambda!"))
    

     七、路由

    • 输入信息: url, get/post query parameters, request body
    • 在 web server 接收到新的 request 时,会解析输入信息,并分发给特定的处理器,这里的分发工作就是“路由”

    a simple http server

    var http = require("http");
    var url = require("url");
    
    
    function route(request){
        return url.parse(request.url).pathname;
    }
    
    http.createServer((request, response) => {
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write(route(request));
        response.end();
    }).listen(8888);
    

      

    • url.parse
    {
        protocol: null,
        slashes: null,
        auth:null,
        host: null,
        port: null,
        hostname: null,
        hash: null,
        search: "?name=xxxxx&url=aaaaa",
        query: {
            name: 'xxxxx',
            url: 'aaaaa'
        },
        pathname: '/user',
        path: '/username=xxxxx&url=aaaaa?',
        href: 'name=xxxxx&url=aaaaa'
    }
    

      

    • 接收请求体:请求体传输是一件耗时的工作,需要异步接收
    var http = require('http');
    var querystring = require('querystring');
    
    http.createServer(function(req, res){
        // 定义了一个post变量,用于暂存请求体的信息
        var post = '';     
    
        // 通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中
        req.on('data', function(chunk){    
            post += chunk;
        });
    
        // 在end事件触发后,通过querystring.parse将post解析为真正的POST请求格式,然后向客户端返回。
        req.on('end', function(){    
            post = querystring.parse(post);
            res.end(util.inspect(post));
        });
    }).listen(3000);
    

      八、全局对象

    • node 中的全局对象名为 global,浏览器中的全局对象名为 window
    • 务必通过 var 来定义变量,因为未定义直接赋值的变量(隐式变量)会被视为全局变量;
    • __filename, __dirname,
    • setTimeout(cb, ms), clearTimeout(t), setInterval(cb, ms)
    • console: log, info, error, warn, dir, time, timeEnd, trace, assert

    当 console.log 接收到多个参数时,会进行格式化输出:

    console.log('Hello world');  // Hello world
    console.log('byvoid%diovyb'); // byvoid%diovyb 
    console.log('byvoid%diovyb', 1991);  //byvoid1991iovyb 
    • process 属性: stdout, stderr, stdin, argv, execPath, execArgv, env, config, pid, title
    • process 方法: abort, chdir, cwd, exit, getgid, setgid, getuid, setdui, kill, uptime …

    九、Node.js常用工具

    1. util.inherits: 实现js对象间的原型继承
    2. util.inspect: 将任意对象转换为字符串
    3. util.isArray(object)
    4. util.isData(obj)
    5. OS,Path,net ,dns,domain

    十、文件系统

    var fs = require("fs");
    
    fs.readFile("filename", (err, data)=> {
        console.log("read file");
    })
    

      

    • fs.open(path, flags[, mode], callback)
    • fs.stat(path, callback)
    • fs.writeFile(file, data[, options], callback)
    • fs.read(fd, buffer, offset, length, position, callback)
    • fs.close(fd, callback)
    • fs.ftruncate(fd, len, callback)
    • fs.unlink(path, callback) : 删除文件
    • fs.mkdir(path[, mode], callback)
    • fs.readdir(path, callback)
    • fs.rmdir(path, callback)

    十一、Express框架

    Express 是一个简洁而灵活的应用框架。

    var express = require('express');
    var app = express();
    
    app.get('/', function (req, res) {
       res.send('Hello World');
    })
    
    var server = app.listen(8081, function () {
    
      var host = server.address().address
      var port = server.address().port
    
      console.log("应用实例,访问地址为 http://%s:%s", host, port)
    
    })
    

      11.1、Request对象

    1. req.app : 访问 express 实例
    2. req.baseUrl
    3. req.body/req.cookies
    4. req.fresh/req.stale
    5. req.hostname/req.ip
    6. req.originalUrl
    7. req.params
    8. req.path
    9. req.protocol
    10. req.query
    11. req.route
    12. req.subdomains
    13. req.accepts()
    14. req.acceptsCharsets/req.acceptsEncodings/req.acceptsLanguages
    15. req.get() : 获取指定的 HTTP 请求头

    11.2、 Response对象

      1. res.app
      2. res.append()
      3. res.set()
      4. res.cookie(name, value [, option]) 
        5.
      5. res.clearCookie()
      6. res.download()
      7. res.get()
      8. res.json()
      9. res.jsonp()
      10. res.location()
      11. res.redirect()
      12. res.render(view, [locals], callback)
      13. res.send()
      14. res.sendFile()
      15. res.set()
      16. res.status()
      17. res.type()

     11.3、路由

    var express = require('express');
    var app = express();
    
    //  主页输出 "Hello World"
    app.get('/', function (req, res) {
       console.log("主页 GET 请求");
       res.send('Hello GET');
    })
    
    
    //  POST 请求
    app.post('/', function (req, res) {
       console.log("主页 POST 请求");
       res.send('Hello POST');
    })
    
    //  /del_user 页面响应
    app.get('/del_user', function (req, res) {
       console.log("/del_user 响应 DELETE 请求");
       res.send('删除页面');
    })
    
    //  /list_user 页面 GET 请求
    app.get('/list_user', function (req, res) {
       console.log("/list_user GET 请求");
       res.send('用户列表页面');
    })
    
    // 对页面 abcd, abxcd, ab123cd, 等响应 GET 请求
    app.get('/ab*cd', function(req, res) {   
       console.log("/ab*cd GET 请求");
       res.send('正则匹配');
    })
    
    
    var server = app.listen(8081, function () {
    
      var host = server.address().address
      var port = server.address().port
    
      console.log("应用实例,访问地址为 http://%s:%s", host, port)
    
    })
    

      11.4、静态文件

    可以使用 express.static 中间件来设置静态文件路径:

    app.use(express.static('public'));
    

     11.5、文件上传

     

    html>
    <head>
    <title>文件上传表单</title>
    </head>
    <body>
    <h3>文件上传:</h3>
    选择一个文件上传: <br />
    <form action="/file_upload" method="post" enctype="multipart/form-data">
    <input type="file" name="image" size="50" />
    <br />
    <input type="submit" value="上传文件" />
    </form>
    </body>
    </html>
    

      服务端代码:

    var express = require('express');
    var app = express();
    var fs = require("fs");
    
    var bodyParser = require('body-parser');
    var multer  = require('multer');
    
    app.use(express.static('public'));
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(multer({ dest: '/tmp/'}).array('image'));
    
    app.get('/index.htm', function (req, res) {
       res.sendFile( __dirname + "/" + "index.htm" );
    })
    
    app.post('/file_upload', function (req, res) {
    
       console.log(req.files[0]);  // 上传的文件信息
    
       var des_file = __dirname + "/" + req.files[0].originalname;
       fs.readFile( req.files[0].path, function (err, data) {
            fs.writeFile(des_file, data, function (err) {
             if( err ){
                  console.log( err );
             }else{
                   response = {
                       message:'File uploaded successfully', 
                       filename:req.files[0].originalname
                  };
              }
              console.log( response );
              res.end( JSON.stringify( response ) );
           });
       });
    })
    
    var server = app.listen(8081, function () {
    
      var host = server.address().address
      var port = server.address().port
    
      console.log("应用实例,访问地址为 http://%s:%s", host, port)
    
    })
    

      12.6、 cookie管理

    可以使用中间件向 Node.js 服务器发送 cookie 信息,以下代码输出了客户端发送的 cookie 信息:

    var express      = require('express')
    var cookieParser = require('cookie-parser')
    var util = require('util');
    
    var app = express()
    app.use(cookieParser())
    
    app.get('/', function(req, res) {
        console.log("Cookies: " + util.inspect(req.cookies));
    })
    
    app.listen(8081)
    

      十二、数据库

  • 相关阅读:
    ssh链接服务器并且拷贝文件
    php读取文件内容
    appendchild的两个正确用法以及ajax
    创业点滴
    随笔——支持IE8的一个ajax的标准写法。
    添加评论,查看评论等——在线留言板4
    删除留言和更新留言——在线留言板3
    git常用命令
    浏览器版本控制
    洛谷 P2296 【寻找道路】
  • 原文地址:https://www.cnblogs.com/LYL-8/p/9639461.html
Copyright © 2011-2022 走看看