解决 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]);
.