zoukankan      html  css  js  c++  java
  • Node笔记(1)

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

    进程

    1.process.argv 用于获取当前进程信息
    0--node.exe的目录
    1--js文件的目录
    2--第一个参数

    process.argv.slice(2) 获取从第一个参数开始的参数



    2.process.env 获取当前系统的环境变量



    3.process.stdout.write('xxx')

    console.log('xxx') = process.stdout.write('xxx ');


    4.process.stdin.on('data',function(data){

    process.stdout.write(data);
    })
    //回车时触发


    传统的java,.net遇到阻塞io时会创建新的线程来处理。 node内部实现其实也是多线程的,(通过线程池)
    //
    多线程都是‘假’的,对于一个cpu核心。创建线程需要时间,线程数量有限,cpu在不同线程间切换需要转换上下文,耗费时间
    多线程的意义并不大(多核心cpu则可能会提升效率)


    node的主线程————事件队列与事件循环圈。

    
    
    

    模块

    exports的实现:

    module是定义在.js文件中的对象

    xxx.js

    console.log(module)

    ....(打印出module对象)

    module中有一个exports对象,可以向内添加属性和方法

    (参考 https://www.cnblogs.com/wbxjiayou/p/5767632.html)

    
    

    写一个require的实现:

    function $require(id){

    const fs = require('fs');

    const path = require('path');

    const filename = path.join(__dirname,id);

    $require.cache = $require.cache || {};

    if($require.cache[filename]){

     return $require.cache[filename].exports;

    }

    const dirname = path.dirname(filename);

     

    let code = fs.readFileSync(filename,'utf8');

    let module = { id:filename,exports:{} };

    let exports = module.exports;

    code=`

    (function($require,module,exports,__dirname,__filename){

     ${code}

    })($require,module,exports,dirname,filename)

    ;`;

    eval(code);

    $require.cache[filename] = module;

    return module.exports;

    }

    var m4 =  $require('../xx.js');

    m4.say();

    ...

    清空require中的缓存机制:

    Object.keys(require.cache).forEach((key)=>{delete require.cache[key]});

    内置模块:

    path:处理文件路径。

    fs:操作(CRUD)文件系统。

    child_process:新建子线程。

    util:提供一系列实用小工具。

    http:提供http服务器功能。

    url:用于解析URL。

    querystring:解析URL中的查询字符串。

    crypto:提供加密和解密功能。

    .. 

    包(Node package manager):

    Buffer

    :读取文件时没有指定编码默认读取的是一个Buffer(缓冲区)

    缓冲区:内存中操作数据的容器。

    为什么要有缓冲区?

    早期JS擅长处理字符串,及HTML文档,不会接触到二进制的数据。

    而在Node中操作数据,网络通信是完全没法以字符串的方式操作的,所以在Node中引入了一个二进制缓冲区的实现,Buffer

    //readfile的方式确实是使用buffer,但是也是一次性读取

    Stream

    读一点数据,处理一点点数据(读到有限长的buffer中,然后再读取出来,)

    写一个歌词滚动效果的实现:

    假定有一个xxx.lrc文件

    方法1.用buffer的方式读入fs.readFile(pathxx,callback)

    在回调函数中对buffer进行tostring转换,然后split掉' ',对于数组中的每一行,用正则提取时间,然后settimeout按时间显示出来

    (由于对每一行处理需要耗费几毫秒的时间,可以设置begin=new Date().getTime() 然后在后面的settimeout中设置新的new Date.getTime()-begin 减掉这个时间)

    方法2.用stream的方式读入 var streamReader = fs.createReadStream(filename);

    var data = '';

    streamReader.on('data',function(chunk){  data+=chunk.tostring(); });

    streamReader.on('end',function(){console.log(data);  };  

    在这里对data进行处理

    方法3.使用readline模块,用stream的方式读入 var streamReader = fs.createReadStream(filename);  

    var rl = readline.createInterface({ input:streamReader });

    var begin = new Date().getTime();

    rl.on('line',(line)=>{....对line进行处理})

    写文件

    默认写入是覆盖 ,可以使用append追加

    方法1.fs.writeFile(path,callback);

    方法2.var streamwriter = fs.createWriteStream(path);

    streamwriter.write('xxx',callback)        (以流的方式写入,防止在内存中读取过多)

    其他文件api

    检查文件、删除、重命名..

    写一个目录树显示的实现:

    思路:通过使用fs.readdirSync

    //打印当前目录所有文件

    const fs = require('fs');
    const path = require('path');

    var target = path.join(__dirname,'./');



    function load(target,depth){


    var prefix = new Array(depth+1).join('| ');
     
    var dirinfo = fs.readdirSync(target);
     
    var dirs = [];
    var files = [];

    dirinfo.forEach(info=>{
    var stats = fs.statSync(path.join(target,info))
    if(stats.isFile()){
     
    files.push(info);

    }else{
     
    dirs.push(info);
    }

    });
     
    dirs.forEach(dir=>{
    console.log(`${prefix}├─${dir}`);
    load(path.join(target,dir),depth+1);
    });

    var count = files.length;

    files.forEach(file=>{
    console.log(`${prefix}${--count?'├':'└'}─${file}`);
    });

    };


    load(target,0);
     

    网络框架

    Express框架的核心是对http模块的再包装

    var http = require("http");
    var app = http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/plain"}); response.end("Hello world!"); });
    app.listen(3000, "localhost");

    var express = require('express');
    var app = express();
    
    app.get('/', function (req, res) {
      res.send('Hello world!');
    });
    
    app.listen(3000);

    中间件(middleware)是处理HTTP请求的函数。

    app.use(function(req,res,next){
     
    if(req.url == '/')
    {
    res.end('Welcome to the homepage! ');
    }else{
    next();
    }
    });

    app.use(function(req,res,next){
    if(req.url == '/about'){
    res.writeHead(200,{'Content-Type':'text/plain'});
    }else{
    next();
    }
    });

    app.use(function(req,res){
    res.writeHead(404,{'Content-Type':'text/plain'});
    res.end('404 Error! ');
    });
     
    也可以这样写:(将地址写在第一个参数里,这样只有对这个地址的请求,才有相应的回应)
    app.use("/home", function(request, response, next) {
      response.writeHead(200, { "Content-Type": "text/plain" });
      response.end("Welcome to the homepage!n");
    });
    
    app.use("/about", function(request, response, next) {
      response.writeHead(200, { "Content-Type": "text/plain" });
      response.end("Welcome to the about page!n");
    });
    
    app.use(function(request, response) {
      response.writeHead(404, { "Content-Type": "text/plain" });
      response.end("404 error!n");
    });
    
    http.createServer(app).listen(1337);

    还可以这样写(*是指所有的请求都要先通过这个中间件)
    app.all("*", function(request, response, next) {
    response.writeHead(200, { "Content-Type": "text/plain" });
    next();
    });

    app.get("/", function(request, response) {
    response.end("Welcome to the homepage!");
    });

    app.get("/about", function(request, response) {
    response.end("Welcome to the about page!");
    });

    app.get("*", function(request, response) {
    response.end("404!");
    });
     
  • 相关阅读:
    01 . Nginx简介及部署
    01 . Ansible原理部署及简单应用
    vue css module
    Expected linebreaks to be 'LF' but found 'CRLF'.
    vue SPA设计 history hash
    vue3 createComponent
    vue3 template refs dom的引用、组件的引用、获取子组件的值
    vue3 父组件给子组件传值 provide & inject
    vue3生命周期
    CSS3 transform变换
  • 原文地址:https://www.cnblogs.com/eret9616/p/8064879.html
Copyright © 2011-2022 走看看