node教程(2022-12-18)

第一章:node的介绍及安装

1.node介绍与安装:
		node是一个基于V8引擎之上的一个JavaScript运行环境 他使得JavaScript可以运行在浏览器以外的地方 相对于大部分的服务器端语言来说 node有很大的不同 他采用了单线程 且通过异步的方式来处理并发问题
		
	
    node.js:运行在服务器端的js
    		用来编写服务器
    	特点:单线程 异步 非阻塞
    			统一API
    
2.安装:		浏览器搜索node下载安装
			使用安装工具nvm来进行安装  
			
			以管理员模式运行终端  在终端输入nvm  version  查看版本号  出现版本号就说明安装成功了
			
			
			常见的nvm 命令:
				---nvm  list  查看当前安装的node版本
				--nvm  install 版本号   安装指定版本的node
				
					安装nvm的时候先配置一下nvm的镜像服务器
				终端输入:			nvm node_mirror https://npmmirror.com/mirrors/node/
			终端输入  npm install latest
	下载完成后 执行 nvm use 版本号 --指定要使用的node版本
	
3.node的使用:
		1.在终端使用js的代码语法
		2.在开发工具里面使用工具自带的终端
		
		node,js和JavaScript有什么区别:
			ECMScript DOM  BOM
		
		

第二章:同步和异步


/*进程和线程:
*           --进程(厂房):
*                   程序运行的环境
*           --线程(工人):
*                   实际进行运算的东西
*
* 同步:--通常情况下代码都是自上而下一行一行的执行的    前面的代码不执行后面的代码也不会执行
*               同步的代码执行会出现阻塞情况
*
* 因此同步会出现 : 一行代码执行慢会影响到整个程序的执行
*
*
*           解决同步问题:
*                       --- Java Python  这些是通过多线程来解决  编写程序去管理  比较麻烦
*                   node.js:单线程的:
*                           ----通过异步的方式来解决
*           异步:  一段代码的执行不会影响到其他代码的执行
* */

console.log("哈哈")
console.log("嘻嘻")
console.log("嘿嘿")
//以上代码就按照顺序来执行 的  第一个没有执行 第二个也不会执行


//例如:同步
function f(a,b) {
    return a+b;
}


//异步:
function f1(a,b,cd) {
    setTimeout(()=>{
    cd(a+b)
    },1000)//10000 毫秒执行这个代码块
}


//因此使用回调函数来返回运算结果
const x=f1(666,777,(x)=>{
    console.log(x)

});
/*异步的代码无法通过return来设置返回值    */
// console.log("我是延时后的代码",x);


const r=f(1,3);
console.log(r);

/*基于回调函数的异步带来的问题:
*       1.代码的可读性差
*       2.可调试性差
*
* 解决方法:因此需要一个东西:可以代替回调函数来给我们返回结果
*       因此使用Promise就出现:可以用来存储数据的对象  Promise存储数据的方式比较特殊 这种特殊方式使得promise可以用来存储
* 异步调用的数据
*
* */


第三章:Promise介绍

function f(a,b,cd) {
//    调用cd函数
    cd(a+b)
}

f(123,456,function (result) {
    console.log("你好  我是cd函数")
    console.log(result)
})
//以上就异步编程


/*因为异步调用必须通过回调函数来返回数据:当我们进行一些复杂的调用时  会出现“回调地狱”
* 问题:异步必须通过回调函数来返回结果  回调函数一朵就会很痛苦
*
*           promise:可以帮助我们解决异步中的回调函数的问题
*               promise就是一个用来存储数据的容器  这个方式使得它里面可以存储异步调用的结果
*
* */

//一.promise的使用

//1.创建promise
//创建promise时 构造函数需要用一个函数作为参数
//promise构造函数的回调函数 他会在创建promise时调用 调用时会有两个参数传递进去
const promise=new Promise((resolve,reject)=>{
    //resolve和reject是两个函数  通过这个函数可以向promise中存储数据
    console.log("回调函数执行了")
//    resolve在执行正常的时候 存储数据   reject在执行错误的时候存储数据
    console.log(resolve,reject)

//    通过函数来向promise中添加数据 好处就是可以用来添加异步调用的数据

})
console.log(promise);

/*读取数据:
*    从promise中读取数据:可以通过promise的实例方法then来读取Promise中存储的数据---注意:需要使用回调函数作为参数
*
* then()需要两个回调函数作为参数 回调函数用来获取Promise中的数据
*       通过resolve存储的数据 会调用第一个函数返回
*       通过reject存储的数据或者出现一次时  会调用第二个函数返回
*               因此可以在第二个函数中编写处理异常的代码
*
* */
promise.then((result)=>{
    console.log("promise中的数据",result)
},(reason)=>{
    console.log("2",reason)
})



/*promise的原理:
*
*       Promise中维护了两个隐藏的属性:
*               promiseResult:用来存储数据  ,对于异步来说
*
*               PromiseState:--记录promise的状态(三种状态:完成(fulfilled):通过resolve存储数据时
*   ,拒绝(rejected):出错了  或通过reject存储数据时
*
*   ,正在进行中(padding))
*       ----state只能修改因此  修改以后就永远不会在变
*
* 流程:当Promise创建时  promisesState初始值为padding:当通过resolve存储数据时,PromiseState 变为fulfilled(完成)
*               promiseResult变为存储的数据
*
*
*           当通过resolve存储数据时,PromiseState 变为rejected(拒绝,出错了)
*               promiseResult变为存储的数据 或异常对象
*       当我们通过then在读取数据  相对于为promise设置了回调函数  如果PromiseState变为fulfilled 则调用then的第一个回调函数返回数据
*   如果PromiseState变为Reject 则调用then的第二个回调函数来进行处理
*
*
* */
const promise2=new Promise((resolve,reject)=>{

    resolve("你好")
})

console.log(promise2)

/*catch()的用法和then类似 但是只是需要一个回调函数作为参数
*           catch()中的回调函数只会在Promise被拒绝的时候才会被调用
*               catch()相对于 then(null,reason=>{})
*               catch()就是一个专门处理Promise异常的方法
* 
* finally()--无论是正常存储数据还是异常了  finally总会执行  但是finally的回调函数中不会接收到数据
*   finally()通常用来编写一些无论成功与否都要执行代码
* */
promise2.catch(reason => {

    console.log(123)
    
})

promise2.finally(()=>{
    console.log()
    
})


/*
* promise1:就是一个用来存储数据对象
* 但是由于Promise存取的方式的特殊 因此可以直接将异步调用的结果存储到Promise中
* */
const promise=new Promise((resolve, reject)=>{
    resolve("我存取了数据  通过resolve来存储")
})

//取出数据
/*
promise.then(result=>{
    console.log(result)
},reason =>
    {
        console.log("出错了",reason)
    }
)*/
function sum(a,b){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            resolve(a+b)//把异步的结果存进去

        },1000)

    })

}

//拿到结果后  丢啊哦用then方法 取出数据
sum(123,456).then(result=>{

    console.log(result)
    sum(result,234).then(result=>{
        sum(result,789).then(result=>{
            sum(result,4567).then(result=>{
                sum(result,8876).then(result=>{

                    console.log(result)
                })
            })

        })

    })
})

/*promise中的:then(return new Promise())
  catch
  finally  中三个方法都会返回一个新的Promise
*       Promise中会存储回调函数的返回值
*   finally的返回值  不会存储到新的Promise中
* */

const p2=promise.then(
    result=>{
        console.log("回调函数",result)
        return "锄禾日当午!"
    }

)
p2.then(result=>{
    console.log(result)

})
console.log(p2)


/*
promise.then(result=>{
    console.log("第一个",result)
    return "你好!"

}).then(result=>{
    console.log("第二个",result)

}).then(result=>{
    console.log("第三个",result)

})*/


//优化版的求和:
sum(123,456)
    .then(result=>result+7)
    .then(result=> result+8)
    .then(result=> console.log(result));

//异常;
promise
    .then(r=> "哈哈")
    .catch(r=>{

        throw new Error("报错")

    return "报错完毕!"
    })

    .then(r=> {
        //如果出现异常 那么久阿婆出异常

        console.log("第二个then",r)
        return "整个异常已经抛出"


    })
//后面的方法读取的是前一个方法的结果     then和catch 读取上一步的执行结果
// 如果上一步的执行结果不是当前想要的结果 则跳过当前的方法
//当promise 出现异常的时,整个调用链中没有出现catch 则异常会向外抛出

/*
* 静态方法:
Promise.resolve(10)  创建一个立即
*
*
* 完成的Promise
*
* */

Promise.resolve(10).then(r=>console.log(r))
// Promise.reject()  创建一个立即拒绝的promise

function f(a,b) {
    return new Promise(((resolve, reject) => {
        setTimeout(()=>{

            resolve(a+b)
        },1000)


    }))
}
Promise.all([sum(123,34),
sum(234,678),
    sum(789,99)
]).then(r=>{
    console.log(r)

})

//Promise.all方法同时返回数组
//这个方法有一个报错整个报错

//Promise.allSettled 这个方法会返回所有数组
Promise.allSettled([sum(123,899),
sum(278,998),
    sum(234,6655)
]).then(r=>{
    console.log(r)
})


//Promise.race([。。。])  这个方法返回执行最快的Promise  不报错
Promise.race([
    sum(123,456),
    sum(373,448),
    sum(2344,66)
    
]).then(r=>{

    console.log(r)
})


//amy 都报错才会整体报错

Promise.any([
    sum(123,67),
    sum(233,45),
    sum(234,344)
    
    
]).then(r=> {

    console.log(r)
})



第四章:宏任务和微任务

/*
*   js代码是单线程  同一个时间内只能做一件事情  他的运行时基于循环机制(event loop)
*
*           调用栈:
*               栈;是一种数据结构 后进先出  调用栈栈放的是要执行的代码
*           --任务队列:
*                   --队列:队列是一种数据结构  先进先出
*               任务队列是将要执行的代码
*               当调用栈中的代码执行完毕后  队列中的代码才会按照顺序一次进入到栈栈执行
*               --在js栈任务队列有两种  :--1.宏任务队列(大部分代码都会去宏任务队列中去排队)
*                                      --2.微任务队列 (Promise的回调函数(then  catch  finally))
*           整个流程:1.执行调用栈栈的代码啊===>2执行微任务队列栈的所有任务===>3.执行宏任务中的所有任务
*
* */
//定时器的作用就是:间隔一段时间后 将函数放入到任务队列中  进行排队  排队等待
/*

//例如:创建一个r 并且读取其中的内容  这个语句就是把1234存储进去  然后再通过than来读取出来
Promise.resolve(1234).then(r=>{
    console.log(r)

})
*/


/*Promise执行原理:在Promise在执行 then就相当于给Promise了回调函数  当Promise的状态从pending变为
*       fulfilled时  then的回调函数就会被放入到任务队列中
*
*
* */

//例如:下面两个语句那个先执行
/*setTimeout(()=>{

    console.log("5秒后出现")

},5000)*/


// console.log(456)


//微任务队列函数:queueMicrotask(()=>{}) 作用就是用来向微任务中添加一个任务
queueMicrotask(()=>{
    console.log("1.微任务!")
})
console.log("2.宏任务")

Promise.resolve().then(()=>{

    console.log("3.微任务立即执行")
})




//手写Promise:
//定义累的思路:  1.先把功能分析清楚  在动手      2.写一点想一点  走一步看异步
//  第一步:创建一个类:
class MyPromise{
    //创建一个变量用来存储Promise的结果
    #result

    //创建一个变量来记录Promise的状态
    #state=0  //padding 0  fulfilled 1  rejected  2





    constructor(executor) {
    //接收一个执行器 作为参数
    //    使用bind()方法  可以绑定当前的this
        executor(this.#resolve.bind(this),this.#reject.bind(this))//调用回调函数  并且拿到当前参数 传递进去

    }

    //私有的resolve()用来存储成功的数据
   /*
   方式一:
   #resolve(value){

        console.log("resolve被调用了  value值是:",value)
        // console.log(this)  不能使用this来定义  整个最后输出的结果是undefined
    }
    */
    //方式二:

    #resolve=(value)=>{
        // console.log(this)    输出MyPromise {}  整个是可以的
    //    禁止值被重复修改:
        if (this.#state!==0){//如果state不等于0  说明值已经被修改  函数直接返回

         return
        }

        this.#result=value
        this.#state=1  //整个表示数据添加成功



    }




    //私有的reject()用来存储拒绝的数据
    #reject(reason){}



//    添加一个用来读取数据的then方法
    then(onFulFilled,onRejected){
    //    两个参数  成功的时候一个状态  失败的时候一个状态

      if (this.#state===1){

          onFulFilled(this.#result)

      }



    }


}

const mp=new MyPromise((resolve,reject)=>{
    resolve("存取数据了  无懈")
resolve("无邪")
resolve("解雨臣")
    console.log("回调函数执行了!!!")

})

console.log(mp)

mp.then((result)=>{


    console.log("读取数据",result)


})





手写Promise的原理:

//手写Promise:
//定义累的思路:  1.先把功能分析清楚  在动手      2.写一点想一点  走一步看异步
//  第一步:创建一个类:
class MyPromise{
    //创建一个变量用来存储Promise的结果
    #result

    //创建一个变量来记录Promise的状态
    #state=0  //padding 0  fulfilled 1  rejected  2


    //创建一个变量来记录Promise的状态
    #callback

    constructor(executor) {
        //接收一个执行器 作为参数
        //    使用bind()方法  可以绑定当前的this
        executor(this.#resolve.bind(this),this.#reject.bind(this))//调用回调函数  并且拿到当前参数 传递进去

    }

    //私有的resolve()用来存储成功的数据
    /*
    方式一:
    #resolve(value){

         console.log("resolve被调用了  value值是:",value)
         // console.log(this)  不能使用this来定义  整个最后输出的结果是undefined
     }
     */
    //方式二:

    #resolve=(value)=>{
        // console.log(this)    输出MyPromise {}  整个是可以的
        //    禁止值被重复修改:
        if (this.#state!==0){//如果state不等于0  说明值已经被修改  函数直接返回

            return
        }

        this.#result=value
        this.#state=1  //整个表示数据添加成功
    //    单resolve执行时  说明数据已经进来了  需要调用then的回调函数
        this.#callback(this.#result)
    }
    //私有的reject()用来存储拒绝的数据
    #reject(reason){}
//    添加一个用来读取数据的then方法
    then(onFulFilled,onRejected){
        //    两个参数  成功的时候一个状态  失败的时候一个状态
        /*
        *目前来说:then只能读取到已经存储到Promise的数据  而不能读取到异步存储的数据
        *
        * */
if (this.#state===1){


//    进入判断说明数据还没有进入到Promise 将回调函数设置为callback
    this.#callback=onFulFilled
}


        if (this.#state===1){
            onFulFilled(this.#result)
        }
    }
}

const mp=new MyPromise((resolve,reject)=>{
    resolve("存取数据了  无懈")
    resolve("无邪")
    resolve("解雨臣")
    console.log("回调函数执行了!!!")

})

console.log(mp)
mp.then((result)=>{
    console.log("读取数据",result)
})

第五章:规范化

1.规范化

/*
*
*  async:通过这个可以快速的创建异步函数
*
* */

/*
function f() {
    return Promise.resolve(10)
}
*/

/*
* 通过async创建的异步函数:异步函数的返回值会自动封装到Promise中返回
*       在async声明的异步函数中可以使用  await关键字来调用异步函数
* */
/*

async function f1() {
    return 10
}


f().then(r=>{

    console.log(r)
})


let result =f1()
console.log(result)*/

function f1(a,b) {
    return new Promise(resolve => {
        setTimeout(()=>{

            resolve(a+b)

        },5000)


    })
}


async function f2() {

//    在这个代码块里面调用

    /*f1(123,455).then(r=>{
        console.log(r)

    })*/
    //当我们通过await去调用异步函数时  他会暂停代码的运行    直到异步代码的运行结果时候  才会将结果返回
    //注意:await只能用于async声明的异步函数中   或es模块的顶级作用域中
    let result=  await f1(123,234)
    console.log(result)
    try {//通过await调用异步代码时  需要通过try---catch来处理异常
        result = await f1(result,56)
        result=await  f1(result,678)
        console.log(result)

    }catch (e)

{
    console.log("出错了!")

}

}
f2()


console.log("全局输出!")
//  await 阻塞的是异步函数内部的代码  不会影响外部代码
/*Promise  解决了异步调用中回调函数的问题      但是链式调用太多以后还是不好看
*       通过同步的方式调用异步代码  await的使用
* */

//如果async中声明的函数中没有写await 那么里面的代码就会依次执行

/*
* 当使用await调用函数后  当前函数后面的所有代码会在当前函数执行完毕后  被放入微任务队列里面
*
* */
 
 
 

2.CommonJS规范

/*1.模块化:
*       随着学习的深入  各种功能越来越复杂  因此不易于维护  所以把整个代码 拆分为一个个小版块
*
* 早期的网页中是没有一个实质的模块化规范的  实现实质化
*
*           1.无法选择要引入模块的那些内容
*           2.在复杂的模块化场景下非常容易出错
*
*           于是就需要在js中引入一个模块化的解决方案
*
*       在node中  默认支持的模块化规范叫做CommonJS   在CommonJS中 一个js文件就是一个模块
*
* CommonJS规范:
*           ---引入模块
*                       使用require()函数来引入模块
*                          ---引入自定义模块的时候 模块名要以./或../开头  扩展名可以省略不写
*                   在CommonJS中  如果省略了扩展名 node会自动补全扩展名
*       先找js   ---->json--->node(特殊)
*
*
* 引入核心模块时:直接写核心模块即可
*
*
*       在定义模块时  模块中的内容默认是不能被外部考到的  可以通过exports来设置暴露的内容
*
*       访问exports的方式有两种:
*                   exports
*                   module.exports
*
*           当我们在其他模块中引入当前模块时  require函数返回的就是exports
*           可以将希望暴露给外部模块的内容设置为exports的属性
* */


//使用require()引入:
/*
const m1= require("./03.Promise进阶")

console.log(m1);
*/

/*console.log(exports);
console.log(module.exports)*/



//也可以向外部暴露特定的值:
/*
exports.a="无邪"
exports.b="解雨臣"
*/


//也可以直接通过module.exports同时到处多个值
/*
module.exports={
    a:"哈哈哈",
    b:"你哈",
    c:()=>{

        console.log("你好  风轻云淡")

    }
}
*/

//比如引入node里面自带的path模块:也可以在核心模块前添加 node:path
const path=require("path")
console.log(path)




/*默认情况下:node会将以下内容视为CommonJS模块
*           1.使用.cjs为扩展名的文件
*              2.当前package,json 的type属性为CommonJS时  扩展名为.js的文件
*               3.当前package.json不包含type属性时  扩展名为.js的文件
*           4.文件扩展名为mjs  cjs json node  js  以外的值时  (type不是module时)
*
*
* 使用文件夹作为模块也是如此
*
* */
//原理:module  exports
//所有的CommonJS的模块都活包装在英国函数中

3.ES模块化规范

module.exports={
    name:"无邪",
    age:18,
    gender:"男"
    
}
/*
* ES模块化:
*
*
* */

//向外部导出内容:
export let a=10
export let b="无邪"
console.log("无邪")

//默认导出
export default function f(a,b) {
    return a+b
}

//导出对象:
// export default let d=20  这个是错误的


//引入模块(整体引入)
/*
const obj=require("./m3")
console.log(obj)
//局部 引入
const name=require("./m3").name
console.log(name)

const gender=require("./m3").gender
console.log(gender)

*/
/*
* 默认情况下  node中的模块化  标准是CommonJS
*           要想使用ES的模块化 可以采用以下两种
*                       1.使用mjs作为扩展名
*                       2.直接修改package.json将模块化规范设置为ES模块  "type": "module" 当我们设置了这个东西  当前项目下所有的js文件
*  都默认es  module
*
*
* */

//导入m4,模块  es自定义模块不能省略扩展名(官方工具)


//改名称语法:通过as来起别名
import { a as hello} from "./m4.js"
console.log(hello)

 import  {a,b}  from "./m4.js"
 console.log(a);
 console.log(b);

//第三种:导入全部
import *  as m4 from "./m4"

console.log(m4.a)


//导入模块的默认导出
//默认导出的内容 可以随意起名  一个模块中只能有一个默认导出
import f from "./m4.js"
console.log(f)

//es模块都是运行在严格模式下
//Es模块化在浏览器中同样支持  但是通常我们不会直接使用
//通常会结合打包工具使用

4.process

11节
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值