vue中一个页面引入多个相同组件重复请求的问题?

⚠️!!!此内容需要了解一下内容!!!

1、会使用promise???

2、 promise跟 async 的区别???

async 会终止后面的执行,后续代码都需要等待 await 接收以后再执行,暂停页面执行顺序

promise不会,只要微任务结束,就会执行同步任务

3、宏任务,微任务执行顺序。???

如下图,页面调用同一个组件N次,如何进行优化

解决方案1.1:接口返回的 promise 状态进行缓存

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>02多请求cache-then</title>
</head>
<body>
  <script>
    let cache = null;

    function getData() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('进入请求接口')
          // resolve({msg: '请求成功', data: [1,2,3,4]})
          reject({msg: '请求失败'})
        }, 100)
      })
    }

    async function initialRequest(msg) {
      console.log(msg)
        if (cache) { return cache; }
   
        if(!cache) {
            // 是第 1 个就去请求
            // (这个示例代码没做容错,自己加)
            try {
              cache = await getData()
               /*
                  不使用await
                  cache = getData()
                  缺点:请求失败的不好处理,每一个调用initialRequest函数,都需要.catch,代码冗余
                
                  使用 await
                  cache = await getData()
                  代码逻辑错误:每一次 initialRequest 函数都会执行,都会产生自己的 getData 函数
                */
            } catch(error) {
              cache = null
              initialRequest('报错请求')
            }
        }
        console.log('使用async,if判断之外的也不会执行')
        return cache;
    }
debugger
    initialRequest('第一请求').then((res) => {
      console.log('一请求--res', res)
    })
    initialRequest('第二请求').then((res) => {
      console.log('二请求--res', res)
    })
    
  </script>
</body>
</html>

有缺陷,在initialRequest函数中

复制代码
1、不使用await
cache = getData()
缺点:请求失败的不好处理,每一个调用initialRequest函数,都需要.catch,代码冗余
                
 2、使用 await
 cache = await getData()
代码逻辑错误:每一次 initialRequest 函数都会执行,都会产生自己的 getData 函数

方案1.2:增加睡眠函数,配合async await 完美使用

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>02多请求cache-async</title>
</head>
<body>

  <script>
   
    let cache = null;
    let count = 0;
    let flag = false

    function getData() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('进入请求接口')
          if (!flag) {
            reject({msg: '请求失败'})
            flag = true
          } else {
            resolve({msg: '请求成功', data: [1,2,3,4]})
          }
        }, 100)
      })
    }

    async function delay(ms = 200) {
      return new Promise(resolve => {
        console.log('进入睡眠函数')
        setTimeout(resolve, ms) // 200 毫秒以后执行这个promise
      });
    }

    async function initialRequest(msg) {
      console.log(msg)
        if (cache) { return cache; }

        if (count++) {
            // 如果有计数说明自己不是第 1 个,就等。注意这里判断的是加之前的 count
            // 循环里最好再加个超时判断
            while (!cache) { 
              const abc = await delay();
              console.log('await会阻止向下循环', abc)
            } // 睡眠是什么意思
        } else {
            try {
              cache = await getData();
            } catch(error) {
              // 判断如果第一个接口请求失败,重新发起请求,直到成功
              count--
              cache = await getData();
              // cache = error
            }
            /*
              使用这个的好处,是从第二次的delay执行完之后都会获取到第一次 getData 执行的结果,
              不用每个函数都添加catch监听错误信息,也可以在try catch中做兼容处理,加入请求失败了,再次发起请求
            */
        }
        console.log('使用async,if判断之外的也不会执行')

        count--;    // 记得减回去,方便以后如果要刷新 cache 的时候用
        return cache;
    }
debugger
    initialRequest('第一请求').then((res) => {
      console.log('一请求--res', res)
    })
    initialRequest('第二请求').then((res) => {
      console.log('二请求--res', res)
    })
    initialRequest('第三请求').then((res) => {
      console.log('三请求--res', res)
    })
   /*  */
  </script>
</body>
</html>

好处:1、如果第一个请求接口异常,可捕获错误,重新发起请求,不影响后面睡眠的函数,最终只需要接收 cache 就行。

2、不用每个函数都添加catch监听错误信息,也可以在try catch中做兼容处理,请求失败了,可再次发起请求(看try catch部分)

那么要做什么文章呢?我们假设这个页面引入多个相同的组件,都是调用同一个 initailRequest 方法。那么在这个方法外部添加一个缓存 cache,组件每次先从这个缓存对象查找存不存在配置数据。如果存在直接获取缓存对象,如果不存在就调用接口获取。但光是这样效果还是和方案1.0结果一样的,同样会调用30次接口。所以我们还需要加一个计数器变量 count。count 的初始值是0,initailRequest 组件每次发送请求时都会给 count 加1。这样子当我们发现是第一次请求时就去调用接口,不是第一次的话就等待,直到第一次请求结束获得数据。逻辑流程图如下:

参考链接:
从解决一个页面请求太多的问题开始的
promise/ async await 的区别

相关推荐
酒尘&1 小时前
JS数组不止Array!索引集合类全面解析
开发语言·前端·javascript·学习·js
学历真的很重要1 小时前
VsCode+Roo Code+Gemini 2.5 Pro+Gemini Balance AI辅助编程环境搭建(理论上通过多个Api Key负载均衡达到无限免费Gemini 2.5 Pro)
前端·人工智能·vscode·后端·语言模型·负载均衡·ai编程
用户47949283569152 小时前
"讲讲原型链" —— 面试官最爱问的 JavaScript 基础
前端·javascript·面试
用户47949283569152 小时前
2025 年 TC39 都在忙什么?Import Bytes、Iterator Chunking 来了
前端·javascript·面试
JIngJaneIL2 小时前
基于Java非遗传承文化管理系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot
+VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue心理健康管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
大怪v3 小时前
【Virtual World 04】我们的目标,无限宇宙!!
前端·javascript·代码规范
狂炫冰美式4 小时前
不谈技术,搞点文化 🧀 —— 从复活一句明代残诗破局产品迭代
前端·人工智能·后端
xw54 小时前
npm几个实用命令
前端·npm
!win !4 小时前
npm几个实用命令
前端·npm