第一章: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)
})
第五章:规范化
/*
*
* 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调用函数后 当前函数后面的所有代码会在当前函数执行完毕后 被放入微任务队列里面
*
* */
09: