• 前端一次性发送几十个请求给后端


    背景

    后端提供一个list列表的接口和列表项详情itemDetail的接口,但是list接口返回的数据不完整,需要继续调用itemDetail获取更完整的数据。所以需要前端并发所有itemDetail接口,来获取详细数据。

    请求走浏览器,因为浏览器本身就有一个队列去控制请求,会限制请求的并发,谷歌一次只让并发同时发送6个请求。所以考虑直接使用promise.all的方式实现好了。

    实现

    Promise.all() MDN:promise处理异步任务并发方式的一种。

    • 当所有输入的 Promise 都被兑现时,返回的 Promise 也将被兑现(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。
    • 如果输入的任何 Promise 被拒绝,则返回的 Promise 将被拒绝,并带有第一个被拒绝的原因。

    (1)请求list接口,并setData存起来

    (2)监听data的变化,依次遍历data数据,请求itemDetail接口

    (3)等待所有itemPromise执行完毕,就可以得到所有item的数据了

    // 数据缓存,同步的方式,可以实时最新的值
    const metricStoreMapRef = useRef();
    
    const handleCallMetricList = async () => {
        try {
          const nodePromises = data?.nodes.map(async (node) => {
            const id = `${node.project_name}-${node.module_name}`;
            // 获取每一项的详细数据
            const metricItem = await getMetricList(node, 'node' as MttkArchitectureSelectedNodeType);
            // 缓存
            metricStoreMapRef.current.metric = {
              ...metricStoreMapRef.current?.metric,
              [id]: metricItem,
            };
    
            return {
              ...node,
              has_error: false,
            };
          });
    
          const edgePromises = data?.edges.map(async (edge) => {
            const { id } = getEdgeId(data?.nodes, edge);
            const metricItem = await getMetricList(edge, 'edge' as MttkArchitectureSelectedNodeType);
            // 缓存
            metricStoreMapRef.current.metric = {
              ...metricStoreMapRef.current?.metric,
              [id]: metricItem,
            };
    
            return {
              ...edge,
              has_error: false,
            };
          });
    
          // 关键点,获取所有的node和edge的数据,使用Promise.all
          const nodeList = nodePromises && (await Promise.all(nodePromises));
          const edgeList = edgePromises && (await Promise.all(edgePromises));
    
          setGraphData({ nodes: nodeList || [], edges: edgeList || [] });
        } catch (err) {
          console.error(err);
          // 如果出错的话,就先展示没有has_error的数据
          notification.error({ message: `Get metrics failed: ${err}` });
          data && setGraphData(data);
        } finally {
          setApiLoading(false);
        }
      };
    
      useUpdateEffect(() => {
        handleCallMetricList();
        // 当请求到图原始的数据后,需要再去请求每个node/edge的metric数据,进而获取has_error
        // data表示列表数据
      }, [data]);
    
  • 相关阅读:
    Linux Day12 ---进程间通信
    Config配置文件读写
    linux网络协议栈源码分析 - 网络层IP网际协议
    微服务--数据同步
    怎么把图片转换成ico图标文件?
    2023软件测试面试题(亲身经历)
    8个提高摸鱼效率的python自动化脚本,提高打工人幸福感~
    python根据文件创建时间删除文件
    Rust通用编程概念(3)
    目标检测算法——收藏|小目标检测的定义(一)
  • 原文地址:https://blog.csdn.net/weixin_43973415/article/details/139752606