当前位置: 首页 > article >正文

前端编程训练 异步编程篇 请求接口 vue与react中的异步

文章目录

      • 前言
      • 代码执行顺序的几个关键点
      • 接口请求
      • vue与react中的异步
        • vue中的异步
        • react的state修改异步

在这里插入图片描述

前言

本文是B站三十的前端课的笔记前端编程训练,异步编程篇

代码执行顺序的几个关键点

  1. 我们可以理解为代码就是一行一行,一句一句是执行(定义变量,方法存在提升情况)
  2. 如果有复杂表达式,表达式从右往左执行(赋值,方法调用,三元等等)
  3. 异步特性,代码一行行执行,但是我们调用了一个异步操作,JS放入异步队列中,等待任务完成,并且当前这次执行已经完成,则执行异步部分

接口请求

接口请求是我们日常工作中最常见的异步操作,通常接口的请求是时间不定的,肯定要花一点时间的。接口请求的异步我们不用考虑什么微任务和宏任务

  1. 获取前三用户的积分,做一个图表。但是问题在于,图表x轴的日期,在一个接口。用户列表在一个接口,用户积分又是另外一个接口
    利用async await一步一步就可以实现但是必须请求完上一个请求才能执行下一步代码会影响性能 我们可不可以让没有依赖的请求同时并发从而优化性能并节省时间呢
<script setup>
import * as echarts from "echarts"

import { onMounted} from "vue";

import axios from "axios";
async function getFinnalData() {

//请求最近五天的日期

const res = await axios.get("http://localhost:8000/getDate")

const dateList = res.data.recentDate;

//获取所有用户列表

const userRes = await axios.get("http://localhost:8000/getUser")

const userList = userRes.data.userList;

//按id排序

userList.sort((preuser, nowuser) => {

return preuser.id - nowuser.id;

})

//筛选出id前三的

userList.splice(3, userList.length - 1);

const _seriesArr = []

for (let i = 0; i < userList.length; i++) {

let _userNumberRes = await axios.get("http://localhost:8000/getUserNumber?id=" + userList[i].id)

let _series = {

name: _userNumberRes.data.name,

data: _userNumberRes.data.recentNumber,

type: "line",

}

_seriesArr.push(_series);

}

//所有数据都到位了,构建最终的options

let option = {

yAxis: {

type: "value"

},

tooltip: {},

xAxis: {

type: "category",

data: dateList

},

series: _seriesArr

}

return option;

}
onMounted(() => {

getFinnalData()

})
</script>

使用Promise.all实现并发效果 优化性能并节省时间

function getFinnalData() {

let option = {

yAxis: {

type: "value"

},

tooltip: {},

xAxis: {

type: "category",

data: []

},

series: []

}

  

//Promise.all,会等数组里两个Promise异步操作都返回了才进入then

Promise.all([

axios.get("http://localhost:8000/getDate"),

axios.get("http://localhost:8000/getUser")

]).then((res) => {

//res[0]-日期接口的返回 res[1]-用户列表接口的返回

//日期数据取出来作为x轴

option.xAxis.data = res[0].data.recentDate

//取出用户列表

const userList = res[1].data.userList

//排序

userList.sort((preuser, nowuser) => {

return preuser.id - nowuser.id;

})

//筛选出id前三的

userList.splice(3, userList.length - 1);

//Promise.all保证三个接口都请求成功了,在进行series的操作

Promise.all([

axios.get("http://localhost:8000/getUserNumber?id=" + userList[0].id),

axios.get("http://localhost:8000/getUserNumber?id=" + userList[1].id),

axios.get("http://localhost:8000/getUserNumber?id=" + userList[2].id)

]).then((res) => {

//三个请求都完成进入then

res.forEach((singleUserNumberres) => {

let _series = {

name: singleUserNumberres.data.name,

data: singleUserNumberres.data.recentNumber,

type: 'line'

}

option.series.push(_series);

//执行完上面的85行,数据就完整了。

let chartDom = document.getElementById('container');

let myChart = echarts.init(chartDom);

myChart.setOption(option);

})

})
  

})
}
  1. 把一个大数组拆分成10个一组,发送给接口,如果有失败的则重试,试超过三次还没成功则停止发送
<script setup>
import axios from "axios";

//循环形成一个100个元素的数组

const arr = [];

for (let i = 0; i < 100; i++) {

arr.push(i);

}

let tryTime = 0;

async function sendSingle(part) {

const res = await axios.get("http://localhost:8001/sendData?part=" + part)

if (!res.data.success) {

tryTime += 1;

if (tryTime >= 3) {

//重试超过三次还没成功,

//就中断后续请求

return false

} else {

return await sendSingle(part);

}

//请求失败的时候进这里

} else {

//如果成功了,我们就把重试次数归0

tryTime = 0;

return true

}

}

async function send() {

//每次循环发一组出去

for (let j = 0; j < arr.length; j += 10) {

const part = arr.slice(j, j + 10);

const res = await sendSingle(part);

if (!res) {

break;

}

}

}

send();

</script>

3,请求接口,根据接口的返回日期,比对本地缓存的日期,看有没有过期
决定是从本地读取key,还是从接口请求key。然后再拿着key请求下一个接口

<script setup>

import { ref } from "vue";

import axios from "axios";

const keyValue = ref('');

axios.get("http://localhost:8002/getAvailableDate").then(async (res) => {

  

if (new Date() - new Date(res.data.date) < 0) {

//没过期

const _key = localStorage.getItem('key')

keyValue.value = _key

} else {

//已过期

const _key = await axios.get("http://localhost:8002/getNew")

keyValue.value = _key.data.key

}

axios.get("http://localhost:8002/getFinnalDate?key=" + keyValue.value).then((res) => {

  

})

})

</script>
  1. 对身份证输入进行三次验证,但是其中同异步验证交杂上一个验证通过才开始下一个,不通过就直接报错,前端验证长是否18位-身份证是否占用-前端验证身份证格式是否符合-身份证是否真实
<script setup>

import axios from "axios";

const value = "112301199402313013";

const testArr = [

(value) => {

if (value.length === 18) {

return true

} else {

return false

}

},

async (value) => {

//这个写成async或者直接return axios.get()都是可以的

const res = await axios.get('http://localhost:8003/isExit?value=' + value);

return !res.data.data

},

(value) => {

const reg = /^[1-9]\d{5}(18|19|20|21|22)?\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|[Xx])$/

return reg.test(value)

},

async (value) => {

const res = await axios.get('http://localhost:8003/isReal?value=' + value);

return res.data.data

}

]

async function test(value) {

for (let i = 0; i < testArr.length; i++) {

const res = await testArr[i](value)

if (!res) {

alert("验证失败")

break;

}

}

}

test(value)

</script>

vue与react中的异步

vue中的异步

在页面更新和DOM操作时,vue中的nextTick有大作用

<script setup>

import axios from "axios";

import { nextTick, ref } from "vue";

const videolist = ref([]);

// extTick是在DOM更新完成后执行的回调函数。Vue是响应式的,当你更新了videolist(例如videolist.value = res.data.videoList),Vue会标记这个数据为"已改变",并且会异步更新DOM。也就是说,页面更新不会立即发生,而是会在下一个事件循环中进行。所以,如果你直接操作DOM(如获取视频元素并调用play方法),可能会发现这些视频元素还没有更新到页面上。nextTick确保你可以在DOM更新后再执行相关操作。

//请求接口-》拿到接口的返回给到videoLsit-》页面根据videoList更新-》更新完成后,获取到所有的videodom-》调用play方法

function show() {

axios.get("http://localhost:8000/videoList").then((res) => {

// 响应式数据更新 页面不会立即跟新

videolist.value = res.data.videoList

//setTimeout或者nextTick可以立即更新

// nextTick(() => {

// const videoArr = document.getElementById("container").getElementsByTagName('video');

// for (let i = 0; i < videoArr.length; i++) {

// videoArr[i].play();

// }

// })

setTimeout(() => {

const videoArr = document.getElementById("container").getElementsByTagName('video');

for (let i = 0; i < videoArr.length; i++) {

videoArr[i].play();

}

})

})

}

</script>

  

<template>

<button @click="show">加载</button>

<div id="container" class="container">

<div class="video" v-for="video in videolist">

<h3>{{ video.name }}</h3>

<video :src="video.videoSrc" muted></video>

</div>

</div>

</template>
<script setup>

import axios from "axios";

import { nextTick, ref } from "vue";

//请求接口-》渲染列表-》判断列表长度-》修改是否显示总长度的控制变量

const tagList = ref([]);

const needShowLength = ref(false);

axios.get("http://localhost:8000/tagList").then((res) => {

tagList.value = res.data.tagList

nextTick(() => {

const width = document.getElementById("container").clientWidth;

  

if (width > 800) {

  

needShowLength.value = true;

} else {

needShowLength.value = false;

}

})

})

</script>

  

<template>

<div id="container" class="container">

<div class="tag" v-for="item in tagList">{{ item }}</div>

</div>

  

<div v-if="needShowLength">总个数:{{ tagList.length }}</div>

</template>
react的state修改异步

react中修改state数据是异步的不是马上更新的。所以我们可以看这样例子
一般方案useEffact监听数据改变,如果可以的话改成用useRef,setTimout不行

function App() {

// const [name, setName] = useState('')

// const [id, setId] = useState('')

// const [age, setAge] = useState('')

// useEffect(() => {

// if (name == '' && age == '' && id == '') {

// axios.get(`http://localhost:8000/tagList?name=${name}&age=${age}&id=${id}`)

// }

// }, [name, age, id]).

  

const name = useRef('');

const id = useRef('');

const age = useRef('');

  

return (

<div className="App">

姓名:<input className='input' onChange={(e) => {

name.current = e.target.value

}}></input>

学号:<input className='input' onChange={(e) => {

id.current = e.target.value

}}></input>

年龄:<input className='input' onChange={(e) => {

age.current = e.target.value

}}></input>

<button onClick={() => {

axios.get(`http://localhost:8000/tagList?name=${name.current}&age=${age.current}&id=${id.current}`)

}}>确认</button>

<button onClick={() => {

const inputList = document.getElementsByClassName("input")

  

for (let i = 0; i < inputList.length; i++) {

console.log(i);

inputList[i].value = ''

}

name.current = '';

id.current = '';

age.current = '';

axios.get(`http://localhost:8000/tagList?name=${name.current}&age=${age.current}&id=${id.current}`)

}}>重置</button>

</div>

);

}

文章到这里就结束了 谢谢大家


http://www.kler.cn/a/412589.html

相关文章:

  • 爬虫与反爬-Ja3指纹风控(Just a moment...)处理方案及参数说明
  • CRTP mixins EBO
  • Linux lsof
  • Pytorch使用手册-Automatic Differentiation with torch.autograd(专题六)
  • python里的数据结构
  • 利用HTML5和CSS来实现一个漂亮的表格样式
  • 决策树分类算法【sklearn/决策树分裂指标/鸢尾花分类实战】
  • git 远端删除分支本地同步删除
  • UE4 iOS Package的过程与XCode工程中没有游戏Content的原因
  • C++学习日记---第12天(函数重载+蓝桥杯基础题)
  • 【C语言篇】从字符海洋到整数大陆——atoi 的探险之旅
  • 服务器记录所有用户docker操作,监控删除容器/镜像的人
  • ByConity ELT 测试体验
  • 【Agorversev1.1数据转换】Agorverse高清地图转OpenStreetMap及SUMO路网
  • 第29天:安全开发-JS应用DOM树加密编码库断点调试逆向分析元素属性操作
  • 【文献阅读】自动化构音障碍严重程度分类:声学特征与深度学习技术的研究
  • Vuex中通过action触发mutation是为什么?[AI]
  • BERT的配置
  • 消息队列实战指南
  • uni-app 自定义平台如何进行 static 目录的条件编译
  • 排序算法之插入排序篇
  • NestJS中使用useClass注入
  • 【ubuntu24.04】hnsw liblibstdc++.so.6: version GLIBCXX_3.4.32‘ not found
  • 【docker集群应用】Docker网络与资源控制
  • vscode中json文件的注释飘红
  • 实现跨语言通信:Rust 和 Thrift 的最佳实践