第一板块
node 介绍
node 优缺点
优点:
-
利用js代码写后端功能
-
采用事件驱动、异步编程,为网络服务而设计。其实Javascript的匿名函数和闭包特性非常适合事件驱动、异步编程。而且JavaScript也简单易学,很多前端设计人员可以很快上手做后端设计。
-
Node.js非阻塞模式的IO处理给Node.js带来在相对低系统资源耗用下的高性能与出众的负载能力,非常适合用作依赖其它IO资源的中间层服务。
-
Node.js轻量高效,可以认为是数据密集型分布式部署环境下的实时应用系统的完美解决方案。Node非常适合如下情况:在响应客户端之前,您预计可能有很高的流量,但所需的服务器端逻辑和处理不一定很多。
-
基于谷歌v8引擎实现,执行速度快。
-
Node.js 的优势是「高并发」,所以很适合用来做 IO 调度,但不太适合用来做复杂计算。
缺点:
-
单线程,单进程,只支持单核CPU,不能充分的利用多核CPU服务器。一旦这个进程崩掉,那么整个web服务就崩掉了。
-
nodejs基于v8,而v8的内存管理机制,限制了node能够使用的内存(64位下面约为1.4G,32位下面只有0.7G),这样在开发过程中稍有不慎,就可能造成内存溢出。
模块化设计
注意:
- 左边
module.exports导出变量,那么在引用的文件中require就只能得到导出的变量(达到不污染变量的目的) - 被导入的文件会立即执行
- 自定义模块的变量,需要导出才能使用,如果不是变量,则会在导入的文件立即执行
- 其中导出部分的写法是对象的解构,还可以写成
- module.exports.a = a
- module.exports.fn = fn
- 导入的文件可以用变量接收,拿到的数据是对象格式,因此就支持
点语法和[]语法 - 导入的文件写法必须保留前缀,后缀可以省略
文件操作
fs.readFile只读取文件(第一个参数为路径,第二个参数为文件读取编码,第三个报错函数)fs.writeFile会覆盖原文件内容(第一个参数为路径,第二个参数为写入的内容,第三个报错函数)fs.appendFile在文件内容的末尾添加内容(第一个参数为路径,第二个参数为添加的内容,第三个报错函数)
读取文件信息
注意:
-
同步代码比异步代码优先执行(就是说最后一行log的同步会比读取文件的异步优先执行)
-
这里获取的
fs是内置模块,这个模块是对文件操作的模块 -
设定变量尽量中const来声明
-
文件操作的方法中的错误参数,都会包含两个属性,错误名称name和错误信息message
-
注意if语句中的一行return代码,如果大括号中只有一行代码的话,大括号可以省去,写在小括号后面汇成一句代码
-
文件操作的第一个路径参数,是
基于文件执行位置,而不是文件所在位置(也就是说在其他位置执行,就直接在那个位置拼接当前的路径中内容),可以考虑用决定路径解决这个问题
path 模块的方法
path.extname获取路径的后缀名path.basename获取路径的基础名称(第二个参数为忽略部分,这里就是忽略.html拿到index)path.join(__dirname,'./txt/1.txt')能够拼接路径 能识别./或../,并且输出系统默认支持的格式
注意
- 在文件操作中,尽量使用这种办法进行
补充
- 拿到基于当前文件的地址
__dirname能够拿到执行文件上一层的路径(一般用这个路径和文件操作的路径进行path.join())__filename能拿到执行文件本身的路径(因此可用性不够大)
注意
- 开发软件不要修改默认路径,以免影响软件之间协同
- 数组和字符串查找方法辨析
str.indexOf()是对字符串的查找,返回的是查找内容的下标arr.findIndex()是对数组的查找,返回的是查找内容的下标arr.find()是对数组的查找,返回的是查找内容的值
control + ~实现vscode中终端的弹出和隐藏切换- 直接在vscode中对要进行node操作的文件,点击右键选择在集成终端中打开
第二板块
npm
- 描述:下载这个模块就能使用npm命令,npm命令用来从官网下载工具包,并且自己也可以制作包上传
- 如果npm用上
-g命令,一般是对命令的设置,比如nrm/nodemon...,都会存在系统的默认路径当中
nodemon 模块
- 描述:全局模块 nodemon 可以监视文件的变化,当文件改变后,nodemon 会帮我们重启服务
- 全局安装命令
npm i -g nodemon - 执行文件命令
nodemon 文件名.js
npm切换国内镜像网站
- 可以使用 全局模块 nrm 来切换镜像网站
- 也可以安装 全局模块 cnpm 工具,直接从淘宝的镜像地址下载第三方模块
- 执行 npm install -g nrm 命令
- nrm 安装后,系统中多了一个命令 nrm
本地模块与全局模块
本地模块
- 一定要初始化
- 安装:npm install 模块名 模块名 …
- 卸载:npm uninstall 模块名 模块名 …
- 安装的本地模块,只能在当前文件夹及其后代文件夹中使用
- 需要通过 require() 加载
全局模块
- 全局模块,安装之前,不需要初始化
- 全局模块,不能通过 require() 加载
- 全局模块,一般都是命令或者工具
- 安装卸载,只需要多加一个 -g
- 全局模块,在任何位置都可以使用
项目依赖和开发依赖
补充
- 下载所有第三方包(程序员):
npm i - 下载项目依赖包(维护人员):
npm i --production
require机制
注意
- require的缓存机制,使用多次也没关系,最终只会执行一次
- 第二三点讲的是必须要有前缀,可以没有后缀,后缀会按照这种机制有容错空间
- 第四点讲的是如果自己设置的模块名和内置模块名重合,则优先加载内置的模块
ES6模块化
- node.js 中默认仅支持 CommonJS 模块化规范
- 若想基于 node.js 体验与学习 ES6 的模块化语法,需要按照如下两个步骤进行配置
- 确保安装了 v13.0.0 或更高版本的 node.js
- 在 package.json 的根节点中添加
"type": "module"节点
注意
如果设置了type为module,就不能用require的形式来获取模块,只能用export default获取模块
三种导入方式
注意
- 导出的形式要和导入的形式相匹配,第一种用对象来接收,第二种是变量接收,就不用使用对象点语法调用,第三种只需要执行那个文件代码的时候使用
注意
- 使用module.exports导出配合require导入的方法
只适用于node的js文件中,而使用export配合import的方法适用于各种情况,项目开发中只是用第二种 - pakage.json中type的规范选择,其中
commonjs是谷歌针对nodejs提出的规范,而module是ECMA组织针对浏览器提出的规范,两种规范的导入导出有区别,适应范围有区别
第三板块(promise)
JS异步任务
- click
- setTimeout/setInterval
- ajax
- fs.readFile/writeFile()
注意
-
回调函数的设置是为了等函数中的代码执行完之后再返回值的情况,为了避免变量赋值为undefied的情况
-
如果说让异步请求按照顺序来执行,就需要将异步操作嵌套起来,就形成了一层层嵌套的 "回调地狱"
Promise
为了解决回调地狱的问题,ES6中新增promise对象
- new Promise(),Promise是一个构造函数,需要new进行创建实例
- 必须
传入一个函数作为Promise的参数,这个函数在 new Promise的时候就会执行 - 函数有 resolve 和 reject 两个形参
- 函数就相当于一个容器,可以将异步任务放到这里
- 将异步任务成功的结果传给 resolve 函数;将失败的信息传给 reject 函数
Promise对象使用
Promise语法阐述:创建Promise对象,在对象中两个形参
resolve和reject是两个函数,是用来依次处理成功和失败两种情况的方法,能够在回调函数中使用方法将需要处理数据作为形参放入到方法中.整个Promise实例对象通过new创建,再通过实例对象调用then方法,通过形参result和error方法处理成功和失败的两种情况(其中的resolve和reject,result和error只是形参名,用其他名字也行,第一个参数为成功的情况第二个位失败的情况)
通过链式编程解决回调地狱问题
优化代码
描述:通过Promise对象的then方法,连接需要同步执行的内容,实现顺序执行的目的,其中每一次的then方法中需要返回下一个Promise实例对象,否则会报错undefined
promise同步异步
- 这里指的异步是指then方法的异步
async关键字
注意:
- async修饰的函数,返回一个Promise对象
- 函数的返回值,将自动包装在resolve的promise中
- 原来利用Promise实现同步过程用到:new创建Promise对象,对象中形参传递resolve函数,利用resolve函数将成功的结果抛出,利用then方法接收;async实现返回Promise对象,并且返回成功的结果
async和await 关键字解决实现同步
描述:利用async修饰函数,使函数能返回Promise对象,并且能够具备Promise抛出的resolve的值,抛出的值能够通过await接收Promise对象返回值,然后赋值给变量(await这个过程能够实现停止当前函数中await后面的代码,让所在函数被调用位置的后面的同步代码先执行.)
补充
- then-fs模块,能够实现获取文件的内容并且返回一个Promise对象,配合async和await实现同步代码
try{} catch{} finally{}(其中finally不管出不出错,都要执行)- ES6中不支持__dirname方法,所以忽略绝对路径问题
- 因为文件模块为异步处理,所以用then-fs模块获取文件为Promise对象的形式,能够进行同步处理
- 回调函数:将一个函数作为另一个函数的参数,这个传递过去的函数就叫做回调函数
第五板块
同步和异步
- 同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
- 异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有
等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。
宏任务和微任务
宏任务(每次执行栈执行的代码就是一个宏任务)
主线程上的执行栈中的代码 每次从事件队列中获取一个事件回调并放到执行栈中执行。
常见宏任务有
- setTimeout
- setInterval
- Ajax
- 事件
- Node中fs可以进行异步的I/O操作
常见微任务有
- Promise.then和Promise.catch (Promise并不是完全的同步,当在Excutor中执行resolve或者reject的时候,此时是异步操作,会先执行then/catch等,当主栈完成后,才会再去调用resolve/reject把存放的方法执行)
- process.nextTick (Node.js 环境,node中实现的api,把当前任务放到主栈最后执行,当主栈执行完,先执行nextTick,再到等待队列中找)
- MutationObserver (创建并返回一个新的 MutationObserver 它会在指定的DOM发生变化时被调用。)
区别:
- 微任务比宏任务占用资源更少
- 前端中微任务基本上只有Promise.then和catch和process.nextTick(Node.js 环境)(可以做排除法,只要不是then和catch都是宏任务)
- 微任务(microtask)是宏任务中的一个部分,它的执行时机是在同步代码执行之后,下一个宏任务执行之前。
请求网站的基本流程
微任务执行顺序面试题
注意
- 判断执行顺序,判断是否是同步任务,再将异步任务分为宏任务和微任务(其中异步任务中的微任务先执行)
补充
- 以前是用
jquery+bootstrap一套开发(但这种方式开始被摒弃,因为不支持Promise);现在使用vue+axios.js+node.js+Promise进行开发 - 异步首选nodejs,最初设计就是多任务
- get请求和a链接能在地址栏发送,form表单能在地址栏发送,post请求不能在地址栏中发送
- 编码encodeURIComponent('内容) 解码decodeURIComponent('内容')
网络通信三大要素
注意:
- 通过ip找到电脑,通过端口找到程序
- http是明文传输,https是加密传输
- 执行过程
express框架
- 第三方模块,是用来快速搭建服务器
注意
- 文件名不能和包名一样,不然包不起作用
- type要设置为module,不然下面的import语法不起作用
- post请求地址在地址栏中输入不起作用
- res.end中只能接受字符串,所以可以换成
res.send(任何数据能够转换成字符串格式,能够识别中文,是express模块新增的方法) - 用nodemon来启动文件,能够在改变之后马上重新启动服务器
- 报错:
两次重复发送 - 报错:
端口被占用
请求参数接收
补充:
- get请求一种是用传递参数的形式请求,另一种是直接在URL后用冒号
:id(叫做URL参数或者路由参数) - 查询参数接收:能够拿到url?后面的传参,并以json的格式获取
- 问号前面的为路由参数,后面的为查询参数;分别通过req.params和req.query实现参数获取
请求参数接收总结
第六板块
同源与跨域
同源
同源,指的是 两个源相同(协议、主机地址、端口相同)
同源策略,是浏览器的一种保护机制
如果非同源,共有以下三种行为受到限制
- DOM无法操作 (A网页和B网页的url非同源,那么不能相互操作对方的DOM)
- Cookie无法操作(A、B两个网站非同源,则无法操作对方的Cookie)
- Ajax请求无效(打开页面的url和请求的接口非同源,则Ajax请求无效,也就是会报错,不能得到服务端的响应结果) 违反了同源策略的请求,就是通常说的跨域请求(指的是不同页面间的请求)
跨域
CORS 模块
引入CORS模块解决跨域问题,能够让前端页面允许 协议、主机地址、端口不同 进行操作
- 下载安装cors:npm install cors
- 加载cors:const cors = require('cors');
- 注册为中间件:app.use(cors()); 注意,这个中间件要放到其他中间件之前
JSONP 模块
原理: 使用script标签模拟发送ajax请求
前端会把接收到的字符串,当做js代码立即执行,并且不会出现跨域问题(因此一般在前端设置一个函数,后端通过JSONP发送执行函数,就是函数调用的形式,前端接收到后能够直接执行,此时的script标签等价于函数调用的一句代码)
递归(在数学计算中)
补充
- 浏览器缓存过程
- 浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
- 浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中
-
if判断句如果比较简单的话,可以写成一句话(其中if小括号后只有一句代码,因此可以省略大括号)
-
开放静态资源
-
利用script标签引入网络上的axios引入到本地
-
JSONP封装(缺点,调用多少次就产生多少个script标签,这个部分了解就行,这段代码还有很多错误)
-
元素.remove()移除元素
注意
- 报错: 后端没有进行跨域配置
- 过程:浏览器能发送出去请求,服务器也响应回来数据,但因为跨域浏览器不接收数据
- 跨域问题只会出现在开发期间,项目上线之后不用考虑这个问题