You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归遍历嵌套对象数组时如何仅在全量遍历完成后返回一次结果

问题原因

加async/await完全解决不了你的问题,属于方向判断错误。
你遇到的多次return、控制台多次输出返回数组的现象,是递归的运行机制导致的:每一层递归调用都会生成独立的函数执行上下文,当前层级的循环遍历完成后,必然会走到函数末尾的return arr语句,这个逻辑和同步/异步没有任何关系。如果你在return语句前加了日志打印,那每结束一层递归就会输出一次数组,自然会看到多次打印结果。
额外说明:你原本的代码逻辑其实已经可以正确收集到所有叶子节点——因为传入的arr是引用类型,所有递归层操作的都是同一个数组实例,中间每一层return返回的都是同一个数组的引用,并不是返回了错误的分段结果。

修正方案

遍历嵌套树结构是纯同步操作,完全不需要改成async函数,以下两种写法都可以实现「遍历完所有节点后仅返回一次最终结果」的需求:

方案1:纯函数写法(推荐)

不需要调用方提前传入空数组,无外部依赖,不会产生共享引用的副作用:

interface Car {
    code?: string;
    children?: Car[];
    [key: string]: any;
}

function getLeafNodes(nodes: Car[]): Car[] {
    const leafList: Car[] = [];
    for (const node of nodes) {
        const hasValidChildren = Array.isArray(node.children) && node.children.length > 0;
        if (hasValidChildren) {
            // 递归收集子分支的叶子节点,拼接到当前结果中
            leafList.push(...getLeafNodes(node.children));
            continue;
        }
        // 无有效子节点且存在code属性,判定为目标叶子节点
        if (Object.prototype.hasOwnProperty.call(node, 'code')) {
            leafList.push(node);
        }
    }
    return leafList;
}

// 调用示例
const result = getLeafNodes(yourRootArray); // 直接拿到完整的叶子节点数组

方案2:沿用原有传参累加的写法

如果你要保留传入数组累加的逻辑,注意不要在递归函数内部加打印日志的逻辑,仅在最外层调用时接收最终结果即可:

async function getChildren(
    obj: Array<Car>,
    arr: Array<Car> = [], // 给arr设置默认空数组,简化调用
) {
    for (const subObj of obj) {
        if (
            Object.prototype.hasOwnProperty.call(subObj, 'children') &&
            subObj.children instanceof Array &&
            subObj.children.length > 0
        ) {
            await getChildren(subObj.children, arr);
        } else if (
            Object.prototype.hasOwnProperty.call(subObj, 'code')
        ) {
            arr.push(subObj);
        }
    }
    // 注意:不要在此处加console.log,否则每一层递归结束都会触发打印
    return arr;
}

// 调用示例
const result = await getChildren(yourRootArray); // 仅最外层拿到最终完整结果
console.log(result); // 此处只会打印一次
关键提醒
  • 网传「改成async可以解决递归多次return」是错误结论,async只会把返回值包装为Promise对象,不会改变递归函数每层都会执行到return语句的本质。
  • 非必要不要把纯同步的遍历逻辑改成async,会徒增不必要的性能开销。

内容的提问来源于stack exchange,提问作者Maximilian546489

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:09:37