zoukankan      html  css  js  c++  java
  • Node.JS学习——学习笔记

    Node.JS——学习笔记

    2020年02月23日11:52:01

    我打算自学NodeJS-通过阅读NodeJS官网来完成。

    https://nodejs.org/dist/latest-v13.x/docs/api/

    https://www.liaoxuefeng.com/wiki/1022910821149312/1023025235359040

    初识Node.js

    Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时。

    安装Node.js

    下载-安装

    运行首个Node.js程序

    1. 创建app.js文件,代码如下
    //创建 app.js文件,使用node app.js 运行
    const http = require('http');
    
    const hostname = '127.0.0.1';
    const port = 3000;
    
    const server = http.createServer((req, res) => {
      res.statusCode = 200;
      res.setHeader('Content-Type', 'text/plain');
      res.end('Hello World');
    });
    
    server.listen(port, hostname, () => {
      console.log(`Server running at http://${hostname}:${port}/`);
    });
    
    1. 使用node app.js命令,运行Node程序。访问。OK。

      运行成功~

    模块(module)

    初始模块

    1. 创建代码,认识模块的调用

      'use strict';
      console.log("hello world");
      var s = "Hello";
      function greet(name){
          console.log(s+","+name)
      }
      function greet2(){
          console.log("1")
      }
      module.exports = {
          greet:greet,
          greet2:greet2
      }
      

      这里自己做了一个小实验,关于多模块的引用和单模块引用的区别。

      'use strict';
      //引入hello 模块
      var greet = require('./hello').greet;
      var greet2 = require('./hello').greet2;
      var name = 'Michael';
      greet("大娃");
      greet2();
      

      在这里我想说,万物皆是对象。

    2. 关于局部变量的问题,这里也解释一下。如果看了node的底层module实现源码,确很容易弄懂。

    基本模块

    global全局对象和process线程对象

    **golbal ** 全局对象

    在前面的JavaScript课程中,我们已经知道,JavaScript有且仅有一个全局对象,在浏览器中,叫window对象。而在Node.js环境中,也有唯一的全局对象,但不叫window,而叫global,这个对象的属性和方法也和浏览器环境的window不同。

    > global.console
    {
      log: [Function: bound consoleCall],
      warn: [Function: bound consoleCall],
      dir: [Function: bound consoleCall],
      time: [Function: bound consoleCall],
      timeEnd: [Function: bound consoleCall],
      timeLog: [Function: bound consoleCall],
      trace: [Function: bound consoleCall],
      assert: [Function: bound consoleCall],
      clear: [Function: bound consoleCall],
      count: [Function: bound consoleCall],
      countReset: [Function: bound consoleCall],
      group: [Function: bound consoleCall],
      groupEnd: [Function: bound consoleCall],
      table: [Function: bound consoleCall],
      debug: [Function: bound consoleCall],
      info: [Function: bound consoleCall],
      dirxml: [Function: bound consoleCall],
      error: [Function: bound consoleCall],
      groupCollapsed: [Function: bound consoleCall],
      Console: [Function: Console],
      profile: [Function: profile],
      profileEnd: [Function: profileEnd],
      timeStamp: [Function: timeStamp],
      context: [Function: context],
      ...//大娃手动省略,太多了
    }
    

    process 线程对象

    process也是Node.js提供的一个对象,它代表当前Node.js进程。

    > process
    process {
      version: 'v13.9.0',
      versions: {
        node: '13.9.0',
        v8: '7.9.317.25-node.28',
        uv: '1.34.2',
        zlib: '1.2.11',
        brotli: '1.0.7',
        ares: '1.15.0',
        modules: '79',
        nghttp2: '1.40.0',
        napi: '5',
        llhttp: '2.0.4',
        openssl: '1.1.1d',
        cldr: '36.0',
        icu: '65.1',
        tz: '2019c',
        unicode: '12.1'
      },
      arch: 'x64',
      platform: 'darwin',
      release: {
        name: 'node',
        sourceUrl: 'https://nodejs.org/download/release/v13.9.0/node-v13.9.0.tar.gz',
        headersUrl: 'https://nodejs.org/download/release/v13.9.0/node-v13.9.0-headers.tar.gz'
      },
      _rawDebug: [Function: _rawDebug],
      moduleLoadList: [
        ...//大娃手动省略。太多了
      ],
      binding: [Function: binding],
      _linkedBinding: [Function: _linkedBinding],
      _events: [Object: null prototype] {
        newListener: [ [Function: startListeningIfSignal], [Function (anonymous)] ],
        removeListener: [ [Function: stopListeningIfSignal], [Function (anonymous)] ],
        warning: [Function: onWarning],
        SIGWINCH: [Function (anonymous)]
      },
      _eventsCount: 4,
      _maxListeners: undefined,
      domain: [Getter/Setter],
      _exiting: false,
      config: {
        target_defaults: {
          cflags: [],
          default_configuration: 'Release',
          defines: [],
          include_dirs: [],
          libraries: []
        },
        variables: {...}//手动省略
      },
      ...//大娃手动省略,内容太多了
      env: {
       ...//大娃手动省略,内容太多了。
      },
      title: 'node',
      argv: [ '/usr/local/bin/node' ],
      execArgv: [],
      pid: 10379,
      ppid: 6491,
      execPath: '/usr/local/bin/node',
      debugPort: 9229,
      argv0: 'node',
      _preload_modules: [],
      [Symbol(kCapture)]: false
    }
        //大娃批注:**一个process,就能查询出当前线程基本上所有的Info**
    

    fs(文件系统模块)

    Node.js内置的fs模块就是文件系统模块,负责读写文件。

    和所有其它JavaScript模块不同的是,fs模块同时提供了异步和同步的方法。

    1. 异步读文件

      'use strict';
      
      var fs = require('fs');
      
      fs.readFile('sample.txt', 'utf-8', function (err, data) {
          if (err) {
              console.log(err);
          } else {
              console.log(data);
          }
      });
      //请注意,sample.txt文件必须在当前目录下,且文件编码为utf-8。
      
    2. 同步读文件

      除了标准的异步读取模式外,fs也提供相应的同步读取函数。同步读取的函数和异步函数相比,多了一个Sync后缀,并且不接收回调函数,函数直接返回结果。

      'use strict';
      
      var fs = require('fs');
      
      var data = fs.readFileSync('sample.txt', 'utf-8');
      console.log(data);
      // 可见,原异步调用的回调函数的data被函数直接返回,函数名需要改为readFileSync,其它参数不变。
      
    3. 异步写文件

      将数据写入文件是通过fs.writeFile()实现的:

      'use strict';
      
      var fs = require('fs');
      
      var data = 'Hello, Node.js';
      fs.writeFile('output.txt', data, function (err) {
          if (err) {
              console.log(err);
          } else {
              console.log('ok.');
          }
      });
      //writeFile()的参数依次为文件名、数据和回调函数。如果传入的数据是String,默认按UTF-8编码写入文本文件,如果传入的参数是Buffer,则写入的是二进制文件。回调函数由于只关心成功与否,因此只需要一个err参数。
      
    4. 同步写文件

      readFile()类似,writeFile()也有一个同步方法,叫writeFileSync()

      'use strict';
      
      var fs = require('fs');
      
      var data = 'Hello, Node.js';
      fs.writeFileSync('output.txt', data);
      
    5. stat()方法:获取文件或者目录的信息

      如果我们要获取文件大小,创建时间等信息,可以使用fs.stat(),它返回一个Stat对象,能告诉我们文件或目录的详细信息:

      'use strict';
      
      var fs = require('fs');
      
      fs.stat('sample.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);
                  // 创建时间, Date对象:
                  console.log('birth time: ' + stat.birthtime);
                  // 修改时间, Date对象:
                  console.log('modified time: ' + stat.mtime);
              }
          }
      });
      
    6. 异步还是同步?

      fs模块中,提供同步方法是为了方便使用。那我们到底是应该用异步方法还是同步方法呢?

      由于Node环境执行的JavaScript代码是服务器端代码,所以,绝大部分需要在服务器运行期反复执行业务逻辑的代码,必须使用异步代码,否则,同步代码在执行时期,服务器将停止响应,因为JavaScript只有一个执行线程

      服务器启动时如果需要读取配置文件,或者结束时需要写入到状态文件时,可以使用同步代码,因为这些代码只在启动和结束时执行一次,不影响服务器正常运行时的异步执行。

    7. 自己写的demo

      'use strict';
      var fs = require('fs');
      // 异步读取文件操作
      fs.readFile('test.js','utf-8',function(err,data){
          if(err){
              console.log('error');
          }else{
              console.log(data);
          }
      })
      
      var content = "hello world";
      // 异步写文件操作
      fs.writeFile('write.js',content,function(err){
          if (err) {
              console.log(err);
          } else {
              console.log('ok');
          }
      })
      
      //stat状态查询
      fs.stat('write.js',function (err,stat) {
          if (err) {
              console.log(err);
          } else {
             console.log(stat.size);
          }
      })
      

    stream

    stream是Node.js提供的又一个仅在服务区端可用的模块,目的是支持“流”这种数据结构。

    大娃评价:和java8提供的stream流结构一样。

    1. 读流 ()

      'use strict';
      
      var fs = require('fs');
      
      // 打开一个流:
      var rs = fs.createReadStream('sample.txt', 'utf-8');
      
      rs.on('data', function (chunk) {
          console.log('DATA:')
          console.log(chunk);
      });
      
      rs.on('end', function () {
          console.log('END');
      });
      
      rs.on('error', function (err) {
          console.log('ERROR: ' + err);
      });
      
    2. 写流 ()

      'use strict';
      
      var fs = require('fs');
      
      var ws1 = fs.createWriteStream('output1.txt', 'utf-8');
      ws1.write('使用Stream写入文本数据...
      ');
      ws1.write('END.');
      ws1.end();
      
      var ws2 = fs.createWriteStream('output2.txt');
      ws2.write(new Buffer('使用Stream写入二进制数据...
      ', 'utf-8'));
      ws2.write(new Buffer('END.', 'utf-8'));
      ws2.end();
      
    3. pipe ()

      'use strict';
      
      var fs = require('fs');
      
      var rs = fs.createReadStream('sample.txt');
      var ws = fs.createWriteStream('copied.txt');
      
      rs.pipe(ws);
      

    HTTP

    要开发HTTP服务器程序,从头处理TCP连接,解析HTTP是不现实的。这些工作实际上已经由Node.js自带的http模块完成了。应用程序并不直接和HTTP协议打交道,而是操作http模块提供的requestresponse对象。

    request对象封装了HTTP请求,我们调用request对象的属性和方法就可以拿到所有HTTP请求的信息;

    response对象封装了HTTP响应,我们操作response对象的方法,就可以把HTTP响应返回给浏览器。

    1. 用Node.js实现一个HTTP服务器程序

      'use strict';
      //导入HTTP模块
      var http = require("http");
      //创建服务器对象
      var server = http.createServer(function(request,response) {
          console.log(request.url);
          response.writeHead(200,{'Content-Type':'text/html'});
          response.end('<h1>hello world</h1>');
      });
      server.listen(8080);
      console.log("Server is running at 8080 port");
      

    URL

    解析URL需要用到Node.js提供的url模块,它使用起来非常简单,通过parse()将一个字符串解析为一个Url对象.

    '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

    处理本地文件目录需要使用Node.js提供的path模块,它可以方便地构造目录

    通过HTTP,URL,FS,PATH

    用代码去认识:构造了一个文件系统

    "use strict";
    var fs = require("fs"),
      url = require("url"),
      path = require("path"),
      http = require("http");
    
    //从命令行参数获取当前线程的root目录,默认目录是当前目录
    var root = path.resolve(process.argv[2] || ".");
    
    console.log("static root dir:" + root);
    
    //创建service
    var server = http.createServer(function(request, response) {
      //获取URL的path
      var pathname = url.parse(request.url).pathname;
      //获取对应的本地文件路径
      var filepath = path.join(root, pathname);
      //获取文件状态
      fs.stat(filepath, function(err, stats) {
        if (!err && stats.isFile()) {
          // 没错
          console.log("200 " + request.url);
          response.writeHead(200);
          fs.createReadStream(filepath).pipe(response);
        } else {
          // 出错
          console.log("404 " + request.url);
          response.writeHead(404);
          response.end("404 Not Fount");
        }
      });
    });
    
    server.listen(8080);
    console.log("server is running at http : 8080");
    

    浏览器访问到本地文件:

    image-20200225055606779

    控制台输出:

    static root dir:/Users/shangyifeng/Desktop/js
    filePath.js:10
    server is running at http : 8080
    filePath.js:35
    404 /
    filePath.js:27
    404 /favicon.ico
    filePath.js:27
    200 /app.js
    filePath.js:22
    404 /filePa
    filePath.js:27
    200 /filePath.js
    filePath.js:22
    200 /app.js
    

    crypto

    crypto模块的目的是为了提供通用的加密和哈希算法。用纯JavaScript代码实现这些功能不是不可能,但速度会非常慢。Nodejs用C/C++实现这些算法后,通过cypto这个模块暴露为JavaScript接口,这样用起来方便,运行速度也快。

    MD5 && SHA1

    const crypto = require('crypto');
    
    const hash = crypto.createHash('md5');
     
    // 可任意多次调用update():
    hash.update('Hello, world!');
    hash.update('Hello, nodejs!');
    
    console.log(hash.digest('hex')); // 7e1977739c748beac0c0fd14fd26a544
    

    官网介绍了很多种语法

    https://nodejs.org/dist/latest-v13.x/docs/api/crypto.html

    over,暂时就这样

    其他API

    官网内容最详细,此行的目的仅是为了简单的了解nodejs,方便自己学习Vue这些前端框架。

    https://nodejs.org/dist/latest-v13.x/docs/api/

    详情内容,以后用到,再查询官网。

    2020年02月25日07:40:07

    规划了一下自己的学习路线,觉得node暂时认知到这里就这样就行了。

  • 相关阅读:
    视频实时增强算法
    FFMPEG中关于ts流的时长估计的实现(转)
    从二维码技术看抢占技术至高点的重要性
    专家观点:不断茁壮的音频生态系统中心(转)
    理解音响系统和房间的相互作用---房间脉冲响应
    Fraunhofer音频技术为MPEG未来高品质3D音频内容传输的标准依据
    Cortex-A15架构解析:它为什么这么强(转)
    骨传导技术(转)
    Faker伪数据生成
    Python数据库连接池DBUtils
  • 原文地址:https://www.cnblogs.com/bigbaby/p/12348995.html
Copyright © 2011-2022 走看看