Node.js递归Async/Await函数返回空对象问题求助
问题修复方案
你遇到的核心问题有两个:
- async函数的返回值特性:async函数默认返回
Promise对象,而非直接的处理结果。如果调用时没通过await或.then()获取Promise的resolved值,直接拿到的Promise对象在表面上会看起来是“空的”(因为它不是你预期的JSON对象)。 - 不必要的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
相关产品推荐
相关产品推荐

