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`: 接收并分配异步任务。也会消耗定时器的时间

`事件轮询`:
	=> 当打开了浏览器后,事件轮询就开始启动了
	=> 先执行一个宏任务,然后再清空整个微任务队列(将所有微任务执行完毕)
	=> 循环往复,直到执行完所有的代码。
相关推荐
腾讯TNTWeb前端团队5 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom10 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom10 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom10 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试