Promise和事件轮询

Promise和事件轮询

今日目标:

1.Promise

  • 要求:能够清楚的说出Promise的特性和静态方法

2.事件轮询

  • 要求:能够理解清楚同步和异步在底层的实现机制

00-回顾

javascript 复制代码
# ajax概述
async javascript and xml: 异步的js和xml

`作用`: 实现客户端和服务器端的数据通信

`优点`: 无刷新提交数据,用户体验好

`缺点`: 对网络SEO支持不友好

`工作原理`:通过js的一个内置构造函数'XMLHttpRequest'来实现`发送异步请求`,并`接收响应的数据`

# ajax发送get请求:
1. 创建一个实例对象
let xhr = new XMLHttpRequest()

2. 配置请求方式和请求地址
// 请求方式和请求地址都是由后端提供接口文档
xhr.open('请求方式', '请求地址?键名=键值&键名=键值...')

3. 发送请求
xhr.send()

4. 监听请求状态
xhr.onreadystatechange = function() {
    // 如果请求状态等于4 ,并且http状态码等于200
    if(xhr.readyState === 4 && xhr.status === 200) {
        // 响应回来的数据是字符串格式
        let res = JSON.parse(xhr.responseText)
    }
}

# ajax发送post请求
1. 创建一个实例对象
let xhr = new XMLHttpRequest()

2. 配置请求方式和请求地址
// 请求方式和请求地址都是由后端提供接口文档
xhr.open('请求方式', '请求地址')

3. 配置请求头
// 配置请求头的目的是为了调整参数的格式
// xhr.setRequestHeader('Content-Type', '提交的参数格式')
// 默认格式:字符串形式,没有对参数做格式处理
xhr.setRequestHeader('Content-Type', 'text/plain')
// 以表单数据的格式提交参数
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// 以json格式提交参数
xhr.setRequestHeader('Content-Type', 'application/json')

4. 发送请求
xhr.send('键名=键值&键名=键值...')

5. 监听请求状态
xhr.onreadystatechange = function() {
    // 如果请求状态等于4 ,并且http状态码等于200
    if(xhr.readyState === 4 && xhr.status === 200) {
        // 响应回来的数据是字符串格式
        let res = JSON.parse(xhr.responseText)
    }
}

# readyState: 请求状态码
0:请求未初始化
1:请求已建立
2:请求已接收
3:请求处理中
4:请求已完成

# http网络传输协议状态码
200:请求成功
304:Not Modified: 未修改。 本次请求的内容和上一次一样,直接从浏览器缓存中将数据拿出来,不再走服务器请求
400:Bad Request: 错误请求。 本次请求没有被服务器正确解析
401:Unauthorized: 未授权。 没有权限访问该接口。 没有登录的时候
403:Forbidden: 拒绝访问。 任何情况下,都不可以访问该接口
404:Not Found: 服务器地址,参数,请求方式错误的时候
405 Method Not Allowed 当前请求的方式服务器不支持
5XX/6XX: 服务器错误

500 Internal Server Error 未知服务器错误
503 Service Unavailable 服务器超负荷


# axios
基于Promise的一个HTTP网络通信的库
`记得引入`: <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.2.2/axios.min.js"></script>

# axios发送get请求
'方式一':
axios.get('请求地址?键名=键值&键名=键值')
	 .then((res) => {
 		// res: 请求成功后,后端的响应数据   
	 })
	 .catch((err) => {
    	// err: 请求失败后的错误信息
})

'方式二'
axios.get('请求地址', {
    params: {
        属性: 值,
        属性:  值
    }
}).then((res) => {
 		// res: 请求成功后,后端的响应数据   
	 })
	 .catch((err) => {
    	// err: 请求失败后的错误信息
})

# axios发送post请求
axios.post('请求地址', {
    属性: 值,
    属性:  值
}).then((res) => {
 		// res: 请求成功后,后端的响应数据   
	 })
	 .catch((err) => {
    	// err: 请求失败后的错误信息
})

// 注意: axios发送post请求默认是以'json格式'提交参数
// 以表单数据格式提交参数:
引入一个qs库:<script src="https://cdn.bootcdn.net/ajax/libs/qs/6.11.0/qs.min.js"></script>
axios.post('请求地址', Qs.stringify{
    属性: 值,
    属性:  值
}).then((res) => {
 		// res: 请求成功后,后端的响应数据   
	 })
	 .catch((err) => {
    	// err: 请求失败后的错误信息
})

# 同步和异步
`同步`:代码从上往下依次执行,前面的代码没有执行完成,后面就不会执行。可能会造成代码阻塞
`异步`:代码从上往下依次执行,如果遇到了异步,就跳过异步,继续执行所有的同步,最后执行异步

# 异步的四种情况
定时器里面的回调函数
事件里面的回调函数
`ajax请求里面的回调函数`: ajax请求的响应顺序是不可控的
Promise里面的回调函数

# 回调地狱
`概念`:当后面的接口需要使用前面接口响应的数据时,把后面的ajax请求写入前面请求的then回调函数里面。这种套娃现象就是回调地狱

`作用`: 解决了ajax请求响应顺序不可控的问题

`缺点`: 代码阅读体验差,不易维护

01-Promise

javascript 复制代码
`作用`: 更加优雅的解决ajax请求响应顺序不可控的问题

`特性`:
	1. Promise是一个构造函数,需要通过new关键词实例化。实例化的过程中,需要接收一个函数参数,该函数又要接收两个函数参数,分别是resolve和reject
    let p = new Promise((resolve, reject) => {})
    
    2. Promise具有三种状态,默认的是`pennding进行中`,还有`fulfilled已完成`和`rejected已失败`
    
    3. 可以通过调用resolve方法将pennding进行中的状态修改为fulfilled已完成,同时会触发实例对象的then方法,顺便将参数带过去

	4. 可以通过调用reject方法将pennding进行中的状态修改为rejected已失败,同时会触发实例对象的catch方法,顺带将参数带过去
    
    5. 无论是已完成还是已失败,只要Promise的状态发生了改变,都会触发实例对象的finally方法
    
    
# Promise支持链式调用
// 注意: 为什么Promise支持链式调用? 原型对象上then,catch和finally方法会返回一个新的Promise的实例对象

# Promise解决ajax请求的响应顺序不可控的原理:
'Promise的实例对象的then方法必须要等到Promise的resolve方法执行后才可以触发。'
`步骤`:
1. 我们可以在前一个Pomise里面发起ajax请求,
2. 请求完成后,再把请求的结果resolve出去,
3. 在实例对象的then方法中接收并发起新的请求

# Promise的静态方法
// all, any和race的区别
// all: 同时执行多个Promise,等到最后一个Promise成功执行后,才结束; 如果其中有一个Promise执行失败,就直接结束
// any: 同时执行多个Promise,只要有一个成功执行,就结束,如果都失败了,才结束, 并且报错
// race: 竞赛。无论成功还是失败,只要有一个结束了,就结束

// allSettled(es2020): 无论成功或失败,直到最后一个执行结束才结束

// resolve: 强制将Promise的状态修改为已完成

// reject: 强制将Promise的状态修改为已失败

02-async和await

javascript 复制代码
`es7的语法。 最优雅的解决ajax请求响应顺序不可控`

`语法`:
// async: 写在函数前面,表示函数里面有异步任务
// await: 写在Promise的前面,等待一个Promise的好的结果 resolve的结果
async 函数名() {
    await 一个Promise
}


// 注意:await必须要等到resolve的结果才可以继续后面的代码
// 原理:将异步代码变成同步执行
async function fun() {
    let r1 = await new Promise((resolve, reject) => {
        axios.post('http://115.159.153.85:8001/postTest', {
            name: '小飞飞'
        }).then(res => {
            console.log('请求1', res);
            resolve(res.data.msg.slice(0, 3))
        })
    })
    console.log(222);
    // console.log(r1, '111111111111');
}

fun();

03-axios的其他语法。(推荐上一种)

javascript 复制代码
axios({
    method: '请求方式',
    url: '请求地址',
    params|data: {
    	属性名:值
    	属性名:值
	}
}).then(res => {}).catch(err => {})

04-事件轮询

javascript 复制代码
`作用`:探讨同步任务和异步任务在浏览器中的执行机制

`单线程`:js是一个单线程的语言,代码从上往下逐行执行,可能会造成代码阻塞
`执行栈`:调用栈,用来存储代码执行环境。代码执行环境可以执行代码。 '先入后出'
`任务队列`:异步任务会被依次放入任务队列中,分为宏任务和微任务。'先进先出'
	=> 宏任务:整个js代码,周期定时器,延时定时器
	=> 微任务:Promise的原型对象的then方法
`web API`: 接收并分配异步任务。也会消耗定时器的时间

`事件轮询`:
	=> 当打开了浏览器后,事件轮询就开始启动了
	=> 先执行一个宏任务,然后再清空整个微任务队列(将所有微任务执行完毕)
	=> 循环往复,直到执行完所有的代码。
相关推荐
阿乐去买菜4 分钟前
2025 年末 TypeScript 趋势洞察:AI Agent 与 TS 7.0 的原生化革命
前端
POLITE35 分钟前
Leetcode 438. 找到字符串中所有字母异位词 JavaScript (Day 4)
javascript·算法·leetcode
创思通信7 分钟前
STM32F103C8T6采 DS18B20,通过A7680C 4G模块不断发送短信到手机
javascript·stm32·智能手机
海绵宝龙10 分钟前
Vue 中的 Diff 算法
前端·vue.js·算法
zhougl99611 分钟前
vue中App.vue和index.html冲突问题
javascript·vue.js·html
止观止11 分钟前
告别全局污染:深入理解 ES Modules 模块化与构建工具
javascript·webpack·vite·前端工程化·es modules
浩泽学编程20 分钟前
内网开发?系统环境变量无权限配置?快速解决使用其他版本node.js
前端·vue.js·vscode·node.js·js
狗哥哥22 分钟前
Vue 3 插件系统重构实战:从过度设计到精简高效
前端·vue.js·架构
巾帼前端23 分钟前
前端对用户因果链的优化
前端·状态模式
不想秃头的程序员26 分钟前
Vue3 中 Lottie 动画库的使用指南
前端