美文网首页
如何避免相同的请求重复发送

如何避免相同的请求重复发送

作者: rainy66 | 来源:发表于2024-12-26 10:00 被阅读0次
export async function lodaData() {
  const res =  await request.get('/api/data')
  return res.data
}

/*
* 完成 asyncOnce函数,函数接受一个异步函数作为参数,
返回一个新的函数,新的函数同时只能被调用一次,多次调用时返回第一次调用的结果。
 */

export function asyncOnce(cb:(...args:any[])=>Promise<any>){
  let isPending = false
  const stack:any[] = []
  return () => {
    return new Promise((resolve,reject) => {
      if(isPending) {
        stack.push(resolve,reject)
        return
      }
      isPending = true
      cb().then((res) => {
        resolve(res)
        stack.forEach(({resolve})=>resolve(res))
      }).catch((err) => {
        reject(err)
        stack.forEach(({reject})=>reject(err))
      })
    })
  }
}

//页面上调用这个函数,只会请求一次数据
export const getUseUser = asyncOnce(lodaData)

如果有参数的话该如何处理

export async function lodaData(id:number) {
  const res =  await request.get('/api/data',{params:{id}})
  return res.data
}

/*
* 完成 asyncOnce函数,函数接受一个异步函数作为参数,
返回一个新的函数,新的函数同时只能被调用一次,多次调用时返回第一次调用的结果。
*/

export function asyncOnce(cb:(...args:any[])=>Promise<any>){
  const map:Record<string,{
    resolve:((value: any) => void)[],
    reject:((err?: any) => void)[],
    isPending:boolean
  } | null> = {}
  return(...args:any[]) => {
    return new Promise((resolve,reject) => {
      const key = JSON.stringify(args)
      if(!map[key]){
        map[key] = {
          resolve:[],
          reject:[],
          isPending:false
        }
      }
      const state = map[key]
      state.resolve.push(resolve)
      state.reject.push(reject)
      if(state.isPending)return
      state.isPending = true
      cb(...args).then((res) => {
        state.resolve.forEach(resolve => resolve(res))
      }).catch((err) => {
        state.reject.forEach(reject => reject(err))
      }).finally(()=>{
        map[key] = null
      })
    })
  }
}
//页面上调用这个函数,只会请求一次数据
export const getUseUser = asyncOnce(lodaData)

asyncOnce 函数内部定义了一个 map 对象,用于存储每个异步调用的状态。
当新函数被调用时,它首先检查 map 中是否已经存在当前调用参数的键(通过 JSON.stringify(args) 生成)。
如果不存在,说明这是第一次调用,将创建一个新的状态对象,并将 isPending 设置为 false。
然后,将调用者的 resolve 和 reject 函数分别添加到状态对象的 resolve 和 reject 数组中。
如果状态对象的 isPending 为 true,则表示异步操作正在进行中,直接返回,不重复执行异步操作。
如果 isPending 为 false,则开始执行异步操作,将 isPending 设置为 true。
异步操作完成后,使用 then 和 catch 分别处理成功和失败的情况,并将结果传递给所有等待的 resolve 和 reject 函数。
最后,在 finally 回调中,将 map 中的当前键值对设置为 null,以便释放资源。

相关文章

  • 获取请求的参数

    发送请求----发送带参数的请求----获取请求参数 如何发送请求 发送请求格式:域名/模块/控制器/方法名模块是...

  • 处理用户发送的get和post请求

    如何处理用户发送的get请求 如何处理用户发送的post请求

  • Promise解决实际问题

    1、取消重复请求 场景:一般点击了A按钮,请求已经发送,请求还没完的时候,再次点击按钮,又会发送新的请求。此场景,...

  • AJAX

    1. 如何发送请求 通过form表单发送请求(包括get请求和post请求),会刷新页面或新开页面 通过a链接发送...

  • node.js处理post请求

    注意:浏览器只能发送get请求,那如何发送post请求呢?发送post请求可以手写ajax请求,但是有跨域问题!所...

  • 常见的HTTP请求头

    常见的HTTP请求头 @(HTTP协议) 当浏览器发送请求给服务器时,根据功能需求的不同,发送的请求消息头也不相同...

  • JAVA服务通过URL下载文件

    概述 如何通过Java发送HTTP请求,通俗点讲,如何通过Java(模拟浏览器)发送HTTP请求。 Java有原生...

  • 面向对象编程设计模式------职责链模式

      职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者...

  • 设计模式之职责链模式

    定义 职责链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送...

  • ajax:asynchronous javascript and

    如何发送请求 1,form可以发送请求,但是将导致刷新页面或者新开页面2,a标签可以发送get请求,同样将导致刷新...

网友评论

      本文标题:如何避免相同的请求重复发送

      本文链接:https://www.haomeiwen.com/subject/ilbbejtx.html