NodeJS必知基础知识(非巨详细)

版权声明: https://blog.csdn.net/qq_32842925/article/details/82759789

Node.js是啥?

node.js是构建在Chrome v8 引擎上的一个javascript 运行环境

node和Chrome一样都是基于事件驱动的异步架构!Chrome是基于事件的交互,而node是基于事件的I/O;

node没有HTML、Webkit和显卡驱动等UI技术支持;

文件引入

如果当前文件夹下有index.js和2.js
2.js 里包含变量a(let a=1)

//2.js
let a=1
global.b=ouyang; //挂载在global全局下,node的全局是global不是window
//index.js
const obj=require("./2.js"); //require请求的就是module.exports的内容
console.log(obj.a); //输出2.js里的a不会成功
console.log(global.b); //ouyang  这样才会成功

node在执行时会把代码重新编译,编译时会把代码打包成字符串放入一个函数里进行编译,所以直接在全局var 或者let声明的变量并不能通过全局直接调用!

模块

//02.js
module.exports=function(){
    console.log("666")
};  //被覆盖
module.exports=123123123; //为模块赋值
// module.exports.num=123;  //可以为模块定义属性
//index.js
const obj=require("./2.js");  //如果不加./ 则在核心模块或第三方依赖模块里找,就不再当前文件夹下找了
console.log(obj); //123123123

重新定向

//2.js
exports=module.exports
exprots.fn=function(){
    
};   //对exports重新定向,并添加新的属性fn,方便index.js的require访问;

node把所有抽象成了事件,node执行时,同步异步差异如下:

// 同步
process.nextTick(()=>{ 
    console.log("1")    //2
})
process.nextTick(()=>{
    console.log("2")    //3
})
//异步
setImmediate(()=>{
    console.log("3")    //6
    process.nextTick(()=>{
        console.log("4")//8
    }
})
setImmediate(()=>{
    console.log("5")    //7
})
setTimeout(function(){
    console.log("8")    //5
},0)
//同步
process.nextTick(()=>{
    console.log("7")    //4
})
console.log("6")        //1

node 输出结果 6 1 2 7 8 3 5 4

事件队列,自动排队
macro-task:script(全部代码) (setInterval setTimeout定时器,同优先级谁先注册谁高) setImmediate I/O

micro-task:process.nextTick Promise=>then

同步的是整体代码,而异步之所以异步是将参数里的回调函数在将来执行

node执行初期执行一个无线循环
while(true){
1.scipt(全部代码),产生同步异步;
2.执行完script后 将micro-task 队列里的事件全部执行;
3.再次执行macro-task 队列里的第二层script,产生第二层的micro-task的
4.紧接着执行micro-task里新产生的事件队列
一直到最里层的macro-task代码产生的micro-task队列执行完毕…
}

Promise.resolve("1").then(res=>console.log(res))
//Promise是同步的,then是异步的(将来执行的)
process.nextTick((=>{
    console.log("2")
})
setTimeout((=>{
    console.log("3")
},0);
console.log("4")

第一次循环:
macro-task:script(第一层代码,检查到有log 4 ) setTimeout=>3
micro-task:process.nextTick=>2 Promise=>then 1
第二次循环:
macro-task:{script(第一层代码,检查到有log 4 )}->第一次已执行 setTimeout=>3->第二次正在执行
micro-task:{process.nextTick=>2 Promise=>then 1}->第一次已执行
mode输出结果 4 2 1 3

总结优先级,可以简单看为:

nextTick > Promise.then > setTimeout > setImmediate

下载包

npm.nodejs.com–>sort by keywords search

运行使用nodejs

实现在控制台进入当前文件夹,node + 文件名 回车执行

  • 初始化项目信息
//初始化项目环境
npm init
//确认初始化对象,输入名称
package name: nodetest
//确认版本等信息,默认回车

//直到出现Is this OK? 回车
//初始化后生成一个package.json 文件,就是上面的配置信息。

npm init -y //一路回车默认配置信息
  • 安装模块
npm install 模块名 参数   //npm install webpack -g 全局安装webpack包,同时安装多个包用空格隔开

//安装时会把相关依赖的包同时安装在当前控制台所在的目录路径
//如安装koa包,--save是安装在当前文件夹,-g是本地,安装在dependencies里代表上线时会使用的包,而koa-router --save-dev 代表生产环境使用的包,将在配置文件package.json 的测试用包,-D代表 --save-dev
npm install koa --save   

//引用时:
const Koa = require("Koa");
const app = new Koa();
app.use(async(ctx)==>{
    ctx.body="这是后台返回的数据"
})

app.listen(3000);


//指定版本
npm install koa@7.0.1 //不指定默认最高版本
  • 添加上传使用用户
npm adduser
Username: 你的名字
Password: (不可见)
...

或者去官网npm.nodejs.com 注册

//登录

npm login
Username:
Password:
Email:

//上传
npm publish 
//上传当前初始化的node环境里的文件,同时会对比以前的文件
  • 如果国外服务器卡顿,使用淘宝镜像

node原生模块

  • 事件模块 events
const events=require("events"); //使用下面的对象时直接加“.EventEmitter”使用 events获得的是构造函数,用new创建实例

如:

const eventEmitter=require("events").EventEmitter;
const myEmitter=new EventEmitter();

//这里有一个异步
setTimeout(()=>{
    //异步的结果出来
},2000);

myEmitter.on("someEvents",()=>{
    console.log("这个某个异步的回调执行函数")
}

或者:

const eventEmitter=require("events").EventEmitter;
const myEmitter=new EventEmitter();
const fn=()=>{
    console.log("这个某个异步的回调执行函数")
}
//这里有一个异步
setTimeout(()=>{
    //异步的结果出来
    myEmitter.emit("fengyu")
},2000);
myEmitter.on("fengyu",fn}; //第一个参数是绑定的监听名号,第二个是回调函数,异步结果执行的函数
  • 自定义模块的原型
const eventEmitter=require("events").EventEmitter;
const myEmitter=new EventEmitter();
function Fn=(name)=>{
    this.name = name;
}

Fn.prototype.__proto__ = EventEmitter.prototype; //将模块的原型赋值到Fn的默认原型

const obj=new Fn("大坏蛋");

obj.on("fy",function(){
  console.log(this.name);  
})
setTimeout(()=>{
    //异步的结果出来
    myEmitter.emit("fy")
},2000);

//node+文件名  在控制台执行
const eventEmitter=require("events").EventEmitter;
const myEmitter=new EventEmitter();

myEmitter.on("newlistenner",function(){
  console.log("绑定了一个新的方法");  
})

myEmitter.on("fy1",()=>{}); //触发log1次
myEmitter.on("fy2",()=>{}); //触发log第二次

//myEmitter.off可以去除
//myEmitter.getMaxListenners()可以设置myEmitter实例的on函数可以绑定的最大事件绑定次数,可以用setMaxListenner(数值)更改,默认10

//myEmitter.listenners()可以查看on对第一个参数名称相同的事件绑定了多少响应回调函数
  • path模块
const path=require('path')
console.log(path.join("a","b"))//用于拼接路径 a/b

console.log(__dirname); //返回文件夹路径
console.log(__filename); //返回文件路径,包含文件名
console.log(path.resolve(__dirname,"test"); //返回一个绝对路径

console.log(path.parse(__filename));  //序列化传入的参数如下格式

/*
{
    root:'/',
    dir:'',
    base:'',
    name:''
}
*/

URL模块

  • 导入URL模块
const {URL} = require("url"); //建议加上.URL,不适用node自己实现的方法
const myUrl=new URL("https://www.baidu.com");
console.log(myUrl); //解析出整个url的各种值并转化为json数据

//search:'' 为查询部分
//URLsearchParams:'' 这是一个类似的map对象 

//如果用parse序列化
const myUrl2=url.parse("https://www.baidu.com");

查询字符串querystring

const qs =require('querystring');

const queryObj=qs.parse(myUrl.search.slice(1))
console.log(queryObj); // 通过. 使用里面的数据

断言 assert

用于判断得到的值是否为期望值

const assert = require('assert');
//assert(布尔值,报错信息)
assert(true,"如果第一个参数的布尔值不为true,这个字符串就为报错信息!")
//或:assert(表达式,预期,报错信息)


image

加密模块

const crypto = require('crypto');

const KEY="fengyu"; 

const obj=crypto.createHash('md5');

obj.update(KEY);

const password=obj.digest('hex'); //输出刚才的结果,1次 参数可以选择进制位数等

文件操作 js

const js = require('fs')

fs.readFile('路径',(err,data)=>{
    if(err) threw err;
    console.log(data);
}); //有Sync 同步 没有回调, 没有Sync 异步有回调 ,错误对象err永远是第一个参数位;
//如果读取错误,err是个json对象,不为null,包含路径,结果,权限等键与值

//输出的data一般是个buffer数据,如果添加第二个参数(进制编码),可以将data转换为其他文字编码,如UTF-8

//异步读取
const js = require('fs')

const fn=async()=>{
    <!--await fs.readFile("./1.txt","utf8",fucntion(err,data){
        if(err)return;
        return data;
    }    //取不到-->  
    const data =await new Promise((resolve,reject)=>{
        fs.readFile("./1.txt","utf8",(err,data)=>{
            if(err) return reject(err)
            resolve(data)
        }
    }
    console.log(data); //取不到
}

image

//同步读取
const js = require('fs');

const data=fs.readFileSync("./2.txt","utf8");//读取错误立马报错


//写
const js = require('fs');
const data="fengyu";
fs.writeFile("./2.txt",data,'utf8',err=>{
    if(err) throw err;
    console.log("写入成功");
}) //utf8 编码参数可选

//写
const js = require('fs');
const data="fengyu";

创建服务器实例

const http=require('http')
const fs=require('fs')
const server=http.createServer((req,res)=>{
    res.writeHead(200,{
    "Content-Type:"text/plain;charset=utf-8"
    "}); //响应头,text/plain 是纯文本,charset设置文字编码
    res.write("向客户端返回数据"); //数据响应,返回值
    res.end()l//结束响应
}); //req requeset, res response
//修改后打断^C,重新执行, 或者安装 npm全局安装nodemon
server.listen(3000); //建议监听1024以上




//返回页面

if(req.method==="GET"){
    res.writeHead(200,{"Content-Type":"text/html;charset=utf-8"})
    switch(req.url){
        case "/":
        res.write(fs.redFileSync("index.html","utf8"));
        <!--
        fs.readFile("index.html","utf8",(err,data)=>{
            res.write(data)
            res.end();//由于是异步的,fs的readFirefile执行在后面的end后,需要把end提到这里面主动提前执行end
        }
        -->
        <!--
        如果使用管道流
        
        fs.createReadStream("index.html").pipe(res);
        -->
    }
    
}

const http=require('http')
const server=http.createServer((req,res)=>{
    const obj={
        a:1,
        b:2
    }
    res.write(JSON.stringfy(obj)
})
server.listen(3000,()=>{
    console.log("服务器监听在localhost:3000")
})

框架 Koa


cosnt Koa= require('koa')

const app =new Koa

//中间件 理论上可以注册任意多个 洋葱模型
app.use(async(ctx,next)=>{
    await next();//提交到下一层
});//ctx context 上下文环境
  • 路由管理
router.get("/",async (ctx,next)=>{
    //只有同时满足在根路径下get请求方式才能进入此中间件,"/"代表根路径,可以改成/home /home/index等等
    
    console.log(1*)
    await next()
    console.log(1=)
    
},async(ctx,next)=>{ //第二个中间件
    console.log(2*)
    await next()
    console.log(2=)
})
// 1*  2*  2=  1=

app.use(router.routes()),
    use(router.alloweMethods());//挂载中间件在app上执行

RESTfull规则

npm安装koa-static 管理静态资源

Pug模板引擎

需要 koa pug koa-views(视图管理)

const Koa=require('koa')
const views=require('koa-views')

const {join}=require('path') // 使用join链接
//pug不需要实例,可以自动识别

const app=new Koa

app.use(views(join(__dirname,"views"),{
    extension:'pug'  //模板pug,views是文件夹名,路径下有个views文件夹
}))  //一定要在其他中间件之前注册模板信息

app.use(async(ctx)=>{
    ctx.render("index.pug") //渲染模板
})

app.listen(3000)

MongoDB

  • 安装

一路默认即可,路径最好在根目录,确认安装环境,如果没有要添加到系统的环境变量里

  • 启动服务:mongod --dbpath Desktop/demo/db 启动服务并初始化目录,完成时会提示连接的监听端口,默认是27017(关闭窗口会断开连接)
  • 客户端连接:mongo
  • 查看数据库集合:show dbs
  • 创建数据库:use DATABASE_NAME
  • 查看正在使用的集合:db

概念: 库database,集合collection

//use 就创建了数据库,并进入当前数据库
> use test //dropDatabase 删除当前数据库
switched to db test
//createCollection创建集合
> db.createCollection("runoob")
{ "ok" : 1 }
> show collections
runoob
//添加数据
> db.runoob.insert({"name" : "fengyu","length":"10"}) 
//db.runoob.drop()删除集合
//find不加参数查找当前目标集合的所有数据,可以传参,内容为数据里的信息
> db.runoob.find()//find({"name":"fengyu"})
  • 其他主机连接服务器数据库
const mongoose=require('mongoose')
const db=mongoose.createConnection("mongodb://localhost:27017/fengyu",{userNewRulParser:true})

//用es6原生的Promise取代MongoDB自实现的Promise
mongoose.Promise=global.Promise

//操作数据库之前,使用Schema设置每个字段的数据类型

db.on("error",console.log.bind(console."数据库连接失败"))
db.on("open",(=>{
    console.log("数据库连接成功")
})


//连接成功-->操作数据库-->设置Schema

const Schema=mongoose.Schema
const JavaScriptSchema=new Schema({
    name:String,
    age:Number,
    sex:{
        type:String,
        default:"男"
    }
})
const JavaScript=db.model("javascript"/*集合名,默认加s*/,JavaScriptSchema/*定义的数据结构*/) //模式化数据,返回一个对象
const data={
    name:"大帅比",
    age:27
}

const data2={
    name:"小清新",
    age:18,
    sex:"女"
}
//插入上面准备的数据

const d1=new JavaScript(data) //实例,结构化数据
d1.save().then(err,,res)=>{  //保存,即数据库的创建插入等操作
    console.log(err)
})

猜你喜欢

转载自blog.csdn.net/qq_32842925/article/details/82759789