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

Node.js递归Async/Await函数返回空对象问题求助

问题修复方案

你遇到的核心问题有两个:

  1. async函数的返回值特性:async函数默认返回Promise对象,而非直接的处理结果。如果调用时没通过await或.then()获取Promise的resolved值,直接拿到的Promise对象在表面上会看起来是“空的”(因为它不是你预期的JSON对象)。
  2. 不必要的async/await:你的代码完全没有异步操作(比如文件读取、网络请求这类需要等待的逻辑),强行添加async/await纯属画蛇添足,反而导致返回值类型改变。

修复方式

方式一:移除async/await(推荐,适配当前同步逻辑)

直接把函数改回同步版本,调用时会直接返回处理后的JSON对象,不会有Promise相关问题:

function isEmpty(value) {
  return (value == null || (typeof value === "string" && value.trim().length === 0));
}

function maskFields(jsonObject, fieldsToMask) {
    if (typeof jsonObject === 'object' && jsonObject !== null) {
        // 创建对象/数组副本,避免修改原输入数据(更安全的写法)
        const result = Array.isArray(jsonObject) ? [...jsonObject] : {...jsonObject};
        
        if (Array.isArray(result)) {
            for (let i = 0; i < result.length; i++) {
                result[i] = maskFields(result[i], fieldsToMask);
            }
        } else {
            for (const key in result) {
                if (result.hasOwnProperty(key)) {
                    result[key] = maskFields(result[key], fieldsToMask);
                    if (fieldsToMask.includes(key) && !isEmpty(result[key])){
                        if(typeof result[key] !== "string")
                        {
                            result[key] = String(result[key]);
                        }
                        const data = result[key].substring(0, 1);
                        const maskedChar = '*'.repeat(result[key].length - 1);
                        const output = data + maskedChar;
                        result[key] = output;
                    }
                }
            }
        }
        return result;
    }
    return jsonObject;
}

方式二:保留async/await(仅当后续需添加异步逻辑时使用)

如果之后需要在函数中加入异步操作(比如从数据库获取掩码规则),可以保留async,但调用时必须正确处理Promise:

// 保留你的async版本(后续可加入真正的异步逻辑)
async function maskFields(jsonObject, fieldsToMask) {
    // 你的原代码逻辑...
}

// 调用方式1:在async函数内使用await
async function processData() {
  const originalObj = { name: "张三", password: "123456", address: { phone: "13800138000" } };
  const maskedObj = await maskFields(originalObj, ['password', 'phone']);
  console.log(maskedObj); // 输出正确的掩码后对象
}
processData();

// 调用方式2:用.then()处理Promise
maskFields(originalObj, ['password', 'phone']).then(maskedObj => {
  console.log(maskedObj);
});

关键提醒

  • 无异步操作的场景下,不要随意添加async/await,它不会让同步代码“异步执行”,只会改变返回值类型。
  • 递归处理对象时,优先创建副本而非修改原对象,能避免原数据被意外篡改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 17:43:15