解决 map 请求接口,通过Promise.all 获取数据,参数覆盖问题

1.场景描述

useEffect(() => {
  tableDs.loadData(
    treeToArr(treeData, FN.children)
      .filter((val) => checkedKeys.includes(val.wbsCode))
      .map((val) => renderItem(val))
  );
}, [treeData, checkedKeys, countDs]);

const renderItem = useCallback(
  async (val) => {
    const hasLeaf = val?.children
      ?.map((v) => v.wbsCode)
      .some((item) => checkedKeys.includes(item));
    if (!hasLeaf) {
      countDs.setQueryParameter(FN.wbsCode, val.wbsCode);
      const { startNum, totalNum } = await countDs.query();
      return {
        ...val,
        hasLeaf,
        startNum,
        totalNum,
      };
    } else {
      return {
        ...val,
        hasLeaf,
      };
    }
  },
  [countDs]
);

通过此种方式获取数据时,发现 wbsCode 会被后一个参数覆盖,导致最终得参数是同一个

2.思路

使用递归函数来循环发送请求

3.解决方案

useEffect(() => {
  const listData = treeToArr(treeData, FN.children)
    .filter((val) => checkedKeys.includes(val.wbsCode))
    .map((val) => ({
      ...val,
      hasLeaf: val?.children
      ?.map((v) => v.wbsCode)
      .some((item) => checkedKeys.includes(item)),
    }));

  const funcs = listData.filter((val) => !val.hasLeaf);

  // 使用递归函数来循环发送请求
  function sendRequest(index) {
    if (index >= funcs.length) {
      // 所有请求发送完成,处理结果
      setLoading(false);
      tableDs.loadData(unionBy(funcs, listData, FN.wbsCode));
      return;
    }
    const wbsCode = funcs[index]?.wbsCode;

    countDs.setQueryParameter(FN.wbsCode, wbsCode);
    countDs.query()
      .then((res) => {
        funcs[index] = {...res, ...funcs[index]}; // 将请求结果保存到对应的索引位置
        sendRequest(index + 1); // 继续发送下一个请求
      })
      .catch(() => {
        funcs[index] = null; // 在错误情况下,仍然保存一个占位符到对应的索引位置
        sendRequest(index + 1); // 继续发送下一个请求
      });
  }

  setLoading(true);
  sendRequest(0);
}, [treeData, checkedKeys, countDs]);

.

posted @ 2022-08-20 23:55  每天都要进步一点点  阅读(72)  评论(0)    收藏  举报