Node.Js(1)

194 阅读8分钟

服务器

B/S架构:Browser(浏览器)/Server(服务器)
C/S架构:Client(客户端)/Server(服务器)

网络协议

网络协议,是指计算机为了能够在网络中进行数据的交换。从而去建立的一个规则、标准

TCP/IP协议

TCP/IP协议,称为网络通讯协议,是互联网中最基本的协议。
TCO/IP协议是一个协议簇,在该协议下还包含了很多的小协议:
http(s):
TCP:
IP:
DNS:
...

在浏览器中输入url发生了什么

1.域名解析

域名就是我们平常所说的网址,'https://www.baidu.com' 中的www.baidu.com 就是百度的域名。
真正访问一个计算机是通过该计算机的IP地址去进行访问,但是由于IP地址不好记,用户体验不好,所以就出现“域名”。
域名解析,指的是通过DNS服务器(域名解析服务器)对域名进行解析,找到该域名所对应的IP地址。

2.建立TCP连接

TCP(传输控制协议)用于保证计算机之间数据传递的完整性和安全性。
三次握手
TCP协议通过三次握手来保证数据传递的完整性和安全性。

1.png
三次握手的目的是为了确保客户端和服务端都处于正常工作的状态。

3.客户端发送请求、服务端处理请求

TCP连接建立成功后,浏览器就可以利用HTTP协议向服务器发送请求了。
服务器接收到请求后,开始处理请求,处理完成后,服务器将处理结果返回(响应)给客户端。

4.关闭TCP连接

客户端接收到服务端发送的数据后,需要通过TCP协议来断开与服务器的连接。
四次挥手

2.png

浏览器渲染页面

浏览器接收到服务器响应的数据后,开始对数据进行解析并渲染。

Nodejs

Node.js是一个基于Chrome V8 引擎的JavaScript运行时。
JavaScript运行时:JS代码的运行环境。
Chrome V8 引擎
浏览器内核:主要分为渲染引擎和js引擎。
渲染引擎:负责解析编译HTML和CSS代码。
JS引擎:负责解析编译js代码。
V8引擎是谷歌公司开发的一款js引擎,是目前公认的解析js代码最快的引擎。
Node.js让JavaScript代码可以在服务端运行。

命令行工具的基础命令

cd:进入某个文件夹。
cd后面可以跟一个路径(建议直接拖文件夹)
cd后面还可以跟一个文件夹名(该文件夹必须是当前路径的子文件夹)
cd .. :返回上一级目录

模块化

每一个js文件都是一个独立的模块,模块与模块之间,是没有关系的。默认情况下模块之间不能进行数据交换。
以前模块化是后端的一种概念,前端是没有模块化的.从ES6开始,前端也引入了模块化的概念。

前端模块化

引入js

引入:引入其他模块中所暴露的数据。
在html中引入js:需要添加一个type=module属性
<script src="./index.js" type="module"></script>

在js中引入js:一个模块中加载另一个模块 import '相对路径'

import './js/a.js';
import './js/b.js';

暴露

暴露:将模块内的数据暴露出去,供其他模块使用。
1.暴露export default(一个模块里只能使用一次)
function foo() {console.log('foo')}
export default {a:1,foo:};

引入import变量名from './a.js'

import bojA from './a.js';
console.log(objA.a);
objA.foo();

2.暴露export

export var a = 1;
export function foo(){
    console.log('hello foo');
    }

引入import {对应的变量名} from '相对路径'

import {a,foo} from './a.js';

后端模块化

commomjs
ECMAScript是一种规范,JavaScript是这个规范的实现。
CommonJS是一种规范,Nodejs是这个规范的实现。
在JS中引入JS
require('./b.js');

暴露和引入
暴露

module.exports.num = 10;
module.exports ={num:10};

引入

const aJS = require('./a.js');
const { num } = require('./a.js');

注意:
1.当使用require去加载某个模块时,除了第一次加载会运行该文件以外(第一次运行完成后会进行缓存),后续的加载都会从缓存中读取该文件。换句话说,同一个文件被require多次,只会执行一次。
2.require中的js文件后缀名可以省略。
3.require中的路径,如果只有模块名,那就说明引入的是第三方下载的模块或者是Nodejs原生自带的模块。

练习

        // const student = {
        //     name:'zs',
        //     age:'20',
        //     sex:'nv'
        // }
        //ES6 解构赋值
        //解构:保持等号左右两侧的结构(数据类型)一致
        // const {name:a,sex:c,age:b} = student;
        // console.log(a,b,c);
        // console.log(student.name,student.age,student.sex);

        //ES6 中关于对象属性的简写,当属性名和属性值是同一个单词时,冒号和其中一个单词可以省略
        //ES6中关于对象方法的简写,可以将冒号和function省略
        // const age = 20;
        // const student = {
        //     name:'zs',
        //     age,
        //     sex:'nv'
        // }
        // console.log(student);  //{name:'sz',age:20,sex:'nv'}

        
        // const student = {
        //     name:'zs',
        //     age:'20',
        //     sex:'nv'
        // }
        //将student的引用地址赋值给了student1 
        // const student1 = student;
        // const student2 = {...student};
        // console.log(student==student1); //true
        // console.log(student==student2);  //false

        
        // const student = {
        //     name:'zs',
        //     age:'20',
        //     sex:'nv'
        // }
        // const student1 = {
        //     ...student,
        //     age:'30'
        // }
        // console.log(student1); //age值改为30

异步

同步和异步

同步:在同一个时间段内,只能做一件事情;
异步:在同一个时间段内,可以同时做多件事情;
JavaScript是一个单线程语言。
console.log('同步1');
setInterval(() => {
    console.log('异步1');
},1000);

console.log('同步2');
console.log('同步3');

setInterval(() => {
    console.log('异步2');
},500);

console.log('同步4');
console.log('同步5');

/*
同步1
同步2
同步3
同步4
同步5
异步2
异步1
异步2
异步2
异步1
异步2
*/

AJAX(特点)

可以实现与服务器的异步通信。
局部刷新页面。

异步解决方案的发展

回调函数
Promise(ES6)
generator(ES6)
async/await(ES7):异步的终极解决方案

Promise

用于方便进行异步操作的回调函数
var promise = new Promise(function (resolve, reject) { 
//定义了一个变量promise,是构造函数Promise的一个实例,Promise接受两个参数,第一个是resolve,第二个是reject。
        setTimeout(resolve,1000)
    })
 
    promise
        .then(
            function () {
                console.log(1)
                return promise
            }
        )
        //实例化的对象(在这里也就是指promise)的then方法接受两个函数为参数,上面的代码中,then里面的function部分,就是promise接受的第一个函数。
        //then方法接收的第一个函数:resolve
        //then方法的第二个参数:rejecte函数

function fn() {
        return new Promise(resolve => {
            setTimeout(resolve,1000)
        })
    }
 
    fn().then(function () {
        console.log(1)
        return fn()
    }).then(function () {
        console.log(2)
        return fn()
    })
 //

async/await

async:用于定义一个异步函数,异步函数的返回值是一个promise对象。
async function foo(){

}
foo();

await:一般用于等待一个promise对象,实际上就是等待一个异步处理结果。

const p = new Promise((resolve,reject) => {
    resolve('1111111');
});
async function foo() {
    const msg = await p;
    console.log(msg);
}
foo(); //1111111

练习

// new Promise((resolve,reject) => {
//     setTimeout(() => {
//         console.log('1');
//         resolve('hello');
//     },10);
//     console.log('2');
//     resolve('world');
// }).then((data) => {
//     console.log(data);
// })
//2 world 1

// async function main(){
//     const data = await Promise.resolve('hello');
//     console.log(data); //hello
//     return data;
// }
// const data = main();
// console.log(data);
// //Promise { }
// //hello

// async function bar(){
//     const num = 100;
//     return num;
// }
// const barData = bar();
// console.log(barData);
// function foo(){
//     const num = 100;
//     return num;
// }
// const fooData = foo();
// console.log(fooData);
// Promise { 100 }
// 100

// function foo(){
//     const num = 100;
//     return num;
// }
// async function bar(){
//     const data = await foo();
//     console.log(data);
// }
// bar();
// console.log(200);
// 200
// 100

// function foo(){
//     const num =100;
//     return num;
// }
// async function bar(){
//     console.log(300);
//     const data = await foo();
//     console.log(data);
// }
// bar();
// console.log(200);
// 300
// 200
// 100


// function foo(){
//     console.log('1');
//     return '2';
// }
// async function bar(){
//     console.log('3');
//     return Promise.resolve('4');
// }
// async function main(){
//     console.log('5');
//     const v1 = await foo();
//     console.log(v1);
//     const v2 = await bar();
//     console.log(v2);
// }
// main();
// console.log('6');
//516234

// function foo(){
//     console.log('1');
//     return '2';
// }
// async function bar(){
//     console.log('3');
//     return Promise.resolve('4');
// }
// async function main(){
//     console.log('5');
//     const v1 = await foo();
//     console.log(v1);
//     const v2 = await bar();
//     console.log(v2);
// }
// main();
// var promise = new Promise((resolve) => {
//     console.log('7');
//     resolve('8');
// });
// promise.then((val) => console.log(val));
// console.log('6');
// 51762384

node中文件操作

//引入文件系统模块
const fs = require('fs'); 
// //1.读取文件内容
// //异步
// fs.readFile('./tes.txt','utf-8',function(err,data) {
//     console.log('err',err);
//     console.log('data',data);
// });
//隐式转换
//0    ''    underfined     null    NaN    false   这六个转成布尔值都是false其他都是true
//同步先执行,异步后执行
//同步
// const result = fs.readFileSync('./tes.txt','utf-8');

// console.log('---------------------');
// console.log(result);

// try {
//     const result = fs.readFileSync('./tes.txt','utf-8');
//     console.log('success',result);
// } catch(error) {
//     console.log('读取失败');
// }


//在文件中写入内容
//新内容会将就内容覆盖掉
//如果路径所对应的文件不存在的话,会自动创建该文件(不会自动创建文件夹)
//异步
// fs.writeFile('./tes.txt','new',function(err){
//     if(err){
//         console.log('写入失败');
//     }else{
//         console.log('写入成功');
//     }
// });
//同步
// fs.writeFileSync('./tes.txt','new');

//3.往文件中追加内容

// fs.appendFile('./tes.txt','新追加',err => {
//     if(err){
//         console.log('失败',err);
//     }else{
//         console.log('success');
//     }
// });
//4.复制文件内容
// fs.copyFile('旧文件路径','新文件路径',err =>{
//     if(err){
//         console.log('失败',err);
//     }else{
//         console.log('成功');
//     }
// });

//5.删除文件
// fs.unlink('文件地址',err =>{
//     if(err){
//         console.log('失败',err);
//     }else{
//         console.log('成功');
//     }
// });

//6.文件重命名
// fs.rename('./tex.txt','./test.txt',err => {
//     if(err){
//         console.log('失败',err);
//     }else{
//         console.log('success');
//     }
// });

node中文件夹操作

//7.创建文件夹
// fs.mkdir('./public',err => {   //创建同级public文件夹
//     if(err){
//         console.log('失败',err);
//     }else{
//         console.log('success');
//     }
// })
//fs.mkdirSync();
//8.删除文件夹(只能删空的文件夹)
// fs.rmdir('./public',err => {   //删除同级public文件夹
//     if(err){
//         console.log('失败',err);
//     }else{
//         console.log('success');
//     }
// })

//9.读取文件夹内容
// fs.readdir('./public',(err,data) => {   
//     if(err){
//         console.log('失败',err);
//     }else{
//         console.log('success',data);
//     }
// })

//10.判断文件/文件夹是否存在
// fs.access('./public',err => {
//     if(err){
//         console.log('文件或文件夹不存在');
//     }else{
//         console.log('文佳或文件夹存在');
//     }
// });
// fs.accessSync();
// fs.existsSync();

//11.查看文件(文件夹)状态,判断当前路径是文件还是文件夹
// fs.stat('./a',function(err,stats){
//     if(err){
//         console.log('失败',err);
//     }else{
//         const isfile = stats.isFile();
//         const isDir = stats.isDirectory();
//         console.log(isfile,isDir);
//     }
// })

封装删除文件方法

const fs = require('fs');
function rmDir(dir){
    //判断 dir是文件还是文件夹
    const stats = fs.statSync(dir);
    if(stats.isFile()){
        //进入if,说明dir是文件,直接删除文件
        fs.unlinkSync(dir);
        console.log(dir+'删除成功');
    }else{
        //进入else,说明dir是文件夹
        //读取文件夹中的内容
        const files = fs.readdirSync(dir);
        //清空文件夹的内容
        files.forEach(item => {
            //判断item是文件还是文件夹
            //进入if,说明item是文件,直接删文件
            //进入else,说明item是文件夹
            //读取文件夹中的内容
            rmDir(`${dir}/${item}`);
        });
        //删除空文件夹
        fs.rmdirSync(dir);
        console.log(dir+'文件夹删除成功');
    }
}
rmDir('./data');

封装移动文件方法

function moveDir(oldDir,newDir){
    try{
        const isAccess = fs.accessSync(newDir);
    }catch(error){
        console.log(newDir+'路径不存在,重新输入');
        const dirs = newDir.split('/');
        const result = dirs.reduce(function(sum,item,index){
           // console.log(sum);
           if(index>1){
            fs.mkdirSync(sum);
           }
            return sum+'/'+item;
        });
        fs.mkdirSync(result);
    }
    fs.renameSync(oldDir,`${newDir}/${oldDir}`);
}