文章目录
Colleagues, we are facing an economic crisis and a political crisis. The public demands that we be responsible to them. We must now address these issues. It is our responsibility to change the current situation in the UK and make solving the economic crisis our top priority. "We only have one chance. This is a moment of life and death." For a better economic plan in western Fujian and a better future for Britain, we must unite as one. We must unite all the talents of the Conservative Party in a "broad" government. We must also build an experienced, disciplined, focused and stable government ——Sunak 20221024
- ES6 模块化语法
- Promse 回调地域问题
- async await 简化Promise调用
- EventLoop
- 宏任务微任务 执行顺序
- ES6模块化
- Promise
- async await
- EventLoop
- 宏任务 微任务
- API接口案例
ES6
回顾:node.js如何实现模块化
node.js遵循了CommonJS
的模块化规范 其中
- 导入其他模块使用
require()
方法 - 模块对共享成员使用
module.exports
对象
模块好处: - 大家都遵循同样的模块化规范写代码,
降低了沟通成本,极大方便了各个模块之间的互相调用
,利人利己
什么是ES6模块化规范
ES6 模块化规范
是浏览器
与服务器
通用的模块化规范。它的出现极大降低了前端开发者模块化,学习成本,开发这不需要向外学习 AMD, CMD,CommonJS模块化规范。
ES6模块化规范
- 每个JS文件都是一个独立的模块
- 导入其他模块化成员使用
import
关键字 - 引入其他模块化成员使用
export
关键字
ES6模块化
node.js中 默认仅支持 CommonJS 模块化规范
,若想基于 node.js 体验与学习 ES6 模块化语法,可以按照两个步骤进行配置:
- 安装node.js
V14.15.1
或更高版本 nodejs - 在package.json 根节点添加
"type":"module"
节点 在文件夹 终端:npm init -y 初始化一个包管理工具 - ES6的模块化主要包含3种
默认导出 默认导入,按需导出按需导入,直接导入并执行模块代码
package.json
{
"type":"module",
"name": "ES6模块化",
"version": "1.0.0",
"main": "index.js",
"license": "MIT"
}
默认导出语法 export default 默认导出成员
let n1 = 10;
let n2 = 20;
function show() {}
export default{
n1,
n2,
show
}
在一个js页面只允许有一个默认导出 export default{}
导入 improt 名称(必须合法) from ./路径
import m1 from './01默认导出.js'
console.log(m1)
终端 node 02默认导入.js
按需导出按需导入
03按需导出.js
export let a1 = 'aa'
export let n1 = 25
export function quer(a,b) {return a + b} quer(1,2)
export default{
a:20
}
04按需导入.js
import info,{n1,a1,quer} from './03按需导出.js'
console.log(n1,a1,quer)
console.log(info)
终端 node 04按需导入.js
每个模块可以使用
多次
按需导出
按需导入成员名称
必须和按需导入
保持一致
按需导入时,可以使用as关键字
进行重命名
按需导入可以和默认导入一起使用
模块化
直接导入并执行模块中代码
只单独执行某个模块中代码
,并不需要得到模块中向外共享成员,此时可以直接导入并执行模块代码
05模块化.js
for(let a = 0; a <= 3; a++){
console.log(a)
}
06test.js
import './05模块化.js'
终端 node 06test.js
Promise
多层回调函数互相嵌套
,形成回调地域
setTimeout(() => {//计时器1
console.log('1')
setTimeout(() => {//计时器2
console.log('2')
setTimeout(() => {//计时器3
console.log('3')
},3000)
},2000)
},1000)
代码耦合性太强 难以维护
,代码可读性比较差
Promise 是一个构造函数
Promise 实例 const p = new Promise()
new 出来 Promise 对象 代表一个一步操作
Promise.prototype 包含一个.then()方法
每一次 new Promise() 构造函数得到实例对象,
都可以通过原型链方式访问到 .then()方法, p.then()
.then()方法用来指定成功失败回调函数
p.then(成功回调函数,失败回调函数)
p.then(result => {}, error =>{})
调用.then()方法,成功回调函数必选,失败回调函数可选。
基于then-fs
由于node.js官方fs模块仅支持
以回调函数方式
读取文件,不支持 Promise 回调方式
需要先运行,安装 then-fs
第三个包,从而基于 Promise 方式读取
下载命令:
npm i then-fs
调用 then-fs 提供 readFile()
方法,异步读取文件内容,它的返回值 Promise 实例对象
可以调用.then()方法
为每个 Promise 异步操作成功
失败
回调函数
//基于Promise 方式读取
import thenFs from 'then-fs'
//.then() 中失败回调函数可选或省略 成功回调函数必写
thenFs.readFile('./1.txt','utf8').then(r1 => {console.log(r1)},err1 => {console.log(err1.message)})
thenFs.readFile('./2.txt','utf8').then(r2 => {console.log(r2)},err2 => {console.log(err2.message)})
thenFs.readFile('./3.txt','utf8').then(r3 => {console.log(r3)},err3 => {console.log(err3.message)})
thenfs方法虽然可以读取文件数据无法保障读取执行顺序
.then()方法
.then()方法返回了一个新 Promise 实例对象
则可以通过下一个,.then() 继续进行处理。通过.then()方法链式调用
,解决了回调地域
Promise支持链式调用
import thenFs from 'then-fs'//返回值Promise实例对象
thenFs.readFile('./1.txt','utf8')//通过.then Promise 实例指定成功之后函数
.then((r1)=>{
console.log(r1)
thenFs.readFile('./2.txt','utf8')//.then返回值新的Promise实例指定成功之后调用函数
.then((r2)=>{
console.log(r2)
thenFs.readFile('./3.txt','utf8')//.then返回一个新的 Promise实例对象
.then((r3)=> {
console.log(r3)//继续调用 .then返回值
})
})
})
.catch 捕获错误
在 Promise 的链式操作中如果发生错误,可以使用 Promise.pototype.catch
方法进行捕获
.catch(){}捕获方法有两种一种在获取接口后捕获
.atch(){} 另一种语句结束捕获这种方式捕获不精确
import thenFs from 'then-fs'//返回值Promise实例对象
thenFs.readFile('./1.txt','utf8')//通过.then Promise 实例指定成功之后函数
.then((r1)=>{
console.log(r1)
thenFs.readFile('./22.txt','utf8')//.then返回值新的Promise实例指定成功之后调用函数
.catch((err)=>{
console.log(err.message)
})
.then((r2)=>{
console.log(r2)
thenFs.readFile('./3.txt','utf8')//.then返回一个新的 Promise实例对象
.then((r3)=> {
console.log(r3)//继续调用 .then返回值
})
})
})
import thenFs from 'then-fs'//返回值Promise实例对象
thenFs.readFile('./1.txt','utf8')//通过.then Promise 实例指定成功之后函数
.then((r1)=>{
console.log(r1)
thenFs.readFile('./22.txt','utf8')//.then返回值新的Promise实例指定成功之后调用函数
.then((r2)=>{
console.log(r2)
thenFs.readFile('./3.txt','utf8')//.then返回一个新的 Promise实例对象
.then((r3)=> {
console.log(r3)//继续调用 .then返回值
})
})
})
.catch((err)=>{
console.log(err.message)
})
Promise.all()
Promise.all() 方法会发起并行 Promise 异步操作,所有异步操作全部结束
才会执行下一步.then操作(等待时机)
import thenFs from "then-fs";//引入
const promiseAll = [//数组
thenFs.readFile('./1.txt','utf8'),
thenFs.readFile('./2.txt','utf8'),
thenFs.readFile('./3.txt','utf8')
]
Promise.all(promiseAll).then(result => {//.all(变量名)方法获取 .then(回调)成功
console.log(result)
})
race() 比赛捕获
import thenFs from "then-fs";//引入
const promiseAll = [//数组
thenFs.readFile('./1.txt','utf8'),
thenFs.readFile('./2.txt','utf8'),
thenFs.readFile('./3.txt','utf8')
]
Promise.race(promiseAll).then(result => {//.race(变量名)比赛捕获 .then(回调)成功
console.log(result)
})
基于Promise 封装自读
- 方法名称定义
getFile
- 接收
形参 fpath
读取文件路径、返回值
为 Promise 实例对象
new Promise()只是创建一个形式上异步操作
创建具体的异步操作
,则需要在 new Promise()构造函数期间,传递一个 function() 函数,具体异步操作定义到 function()函数内部
.then 两个实参
.then()指定成功,失败
回调函数,可以在 function 形参中
进行接收
import fs from 'fs'
function getFile(fpath){//只要有人 new promise方法出去
return new Promise (function(resolve,reject){//有谁 new Promise 方法就会得到 Promise 实例
fs.readFile(fpath,'utf8',(err,dataStr) =>{//在函数内部创建一个读文件
if(err) return reject(err)
resolve(dataStr)
})
})
}
getFile('./11.txt').then((r1)=>{console.log(r1)}).catch(err=>{
console.log(err.message)
})
Promise 异步操作结果
,可以调用 resolve reject
回调函数进行处理
async await
async await
是 ES8
引入新语法,用来简化 Promise 异步操作
在async awai 出现之前,开发者只能通过.then()的方式
处理 Promise异步操作
.then 链式调用优点
解决回调地域问题
.then 链式调用缺点
代码阅读性差
import thenFs from 'then-fs'
async function getAllFile() {
let r1 = await thenFs.readFile('./1.txt','utf8')
console.log(r1)
let r2 = await thenFs.readFile('./2.txt','utf8')
console.log(r2)
let r3 = await thenFs.readFile('./3.txt','utf8')
console.log(r3)
}
getAllFile()
async await
注意事项
function 中用到await
必须使用async
在 async 方法中,第一个 await 之前代码会同步执行
,await之后代码 会异步执行
console.log('a')//1
async function getAllFile() {
console.log('b')//2 b执行同步
//下面都是异步执行 等待同步执行完成异步在执行
let r1 = await thenFs.readFile('./1.txt','utf8')
console.log(r1)//4 111
let r2 = await thenFs.readFile('./2.txt','utf8')
console.log(r2)//4 222
let r3 = await thenFs.readFile('./3.txt','utf8')
console.log(r3)//4 333
console.log('d')//5 d
}
getAllFile()//2调用 b
console.log('c')//3 c 同步
同步任务异步任务
为了防止某个耗时任务
到最后程序假死
问题,javaScript把任务分成两类
同步任务
synchronous
非耗时任务
在主线程排队任务- 只有前一个任务执行完毕,才执行下一个
- 异步任务 asyncronous
- 又叫做
耗时任务
,异步任务由JavaScript委托
宿主环境执行(执行环境如果在JS环境就是JS环境,node.js就是node.js环境) - 当异步任务执行完成,会
通知JavaScript
主线程执行异步任务回调函数
- 同步任务由JavaScript 主线程执行
- 异步任务
委托给
宿主环境- 已经完成异步任务
对应回调函数
,会被加入到任务队列执行- JavaScript主线程
执行栈
被清空,会读取任务队列中回调函数
EventLoop
JavaScript 主线程“任务队列”中读取异步任务回调函数,放到执行栈中一次执行。
这个过程循环不断,这个运行机制EventLoop事件循环
面试题执行顺序
console.log('A')//执行任务首先看同步任务顺序执行不需要等待 A D 异步等待有(B,C) C不需要等待0秒执行 B需要等待 结果 ADCB
thenFs.readFile('./1.txt').then((dataStr)=>{
console.log('B')
})
setTimeout(()=>{console.log('C')},0)
console.log('D')
宏任务微任务
JavaScript 把异步任务分为 两类
宏任务
- 异步Ajax请求
- setTimout setlnterval
- 文件操作
- 其他任务
微任务
- Promise.then .catch .finally
- prcess.netxTick
- 其他微任务
宏任务执行顺序
宏任务: 当所有的宏任务执行完成判断有没有微任务有执行没有执行宏任务
JS执行是单线程宏任务按次序执行,检查是否有微任务
执行微任务宏任务被执行``所有微任务执行完毕,
开始执行下一个宏任务
面试题宏任务微任务
setTimeout(function(){//计时器宏任务 等待 4
console.log('1')
})
new Promise(function(resolve){//new Promise 实例化对象立即执行 宏任务 1
console.log('2')
}).then(function(){//.then 微任务 等待 检查有微任务执行 3
console.log('3')
})
console.log('4')//同步立即执行 2
//2431
API
- 搭建项目基本结构
- 创建基本服务器
- 创建
db
数据库操作模块 - 创建
user_ctrl
业务模块 - 创建
user_router
路由
搭建项目基本结构
启动ES6模块
终端下载 npm init -y
- 在package.json 中声明
"type": "module",
- npm i express@4.17.1mysql2
根目录/app.js
import express from 'express'
const app = express()
app.listen(80, () =>{
console.log('server running at http://127.0.0.1')
})
终端命令: nodemon app.js
终端回应:server running at http://127.0.0.1
db/index.js
import mysql from 'mysql2'
// 创建数据库连接对象
const pool = mysql.createPool({//创建数据库链接对象
host:'127.0.0.1'//指定操作数据库
port:3306,//数据库端口号
database:'my_db_01',//操作数据库
user:'root',//登录数据库端口号
password:'admin123'//密码
})
//导出链接对象供外界使用 pool不支持promise对象所以导出pool.promise
export default pool.promise()
controller/user_ctrl.js
import db from '../db/index.js'
export async function getAllUser(req,res){
const [rows] = await db.query('select id, username,nickname from ev_users')
// @ts-ignore
rows.send({
status:0,
message:'获取列表数据',
data:rows
})
}
getAllUser()
user/user_router.js
import express from 'express'
import {getAllUser} from '../controller/user_ctrl.js'
const router = new express.Router()
router.get('/user',getAllUser)
export default router
app.js
import express from 'express'
import userRouter from './router/user_router'
app.use('/api',userRouter)
const app = express()
app.listen(80, () =>{
console.log('server running at http://127.0.0.1')
})
Vue
前端工程化
实际开发
模块化
js 模块化 css模块化 资源板块化
组件化
复用现有的 UI 结构 样式 行为
规范化
目录结构化 编码规范化 接口规范化 文档规范化 Git分支管理
自动化
自动化结构 自动部署 自动测试
Webpack 基本使用
创建表格隔行变色
- 新项目空白目录,并
运行 npm init -y
,初始化包管理配置文件package.json
- 创建
src
- 创建
src -> index.html
首页src -> index.html
- 初始化首页基本结构
运行 npm install jquery -S
安装 JQuery- ES6模块化方式陷入jQuery 实现隔行变色