Vue.js递归函数调用Axios解析JSON Schema $ref时返回结果异常
问题根因
两次实现的问题分别是:
- 同步写法中
$axios.get是异步请求,代码不会等待接口返回就继续执行后续递归逻辑,此时schema.properties还未被赋值,因此indicators解析结果为空对象。另外原代码中axios get传参格式错误,参数需要包裹在{params: {}}结构中才会正确拼接在url后。 - async/await改写版本的问题是两处未正确等待异步结果:一是递归调用解析函数时没有加await,二是
forEach循环本身不支持异步等待,直接将递归返回的Promise实例赋值给了属性,因此结果里出现Promise对象。
可运行修复代码
async parseJsonToObject(schema: any) { if (!schema) return {}; // 处理$ref远程拉取逻辑,拉取完成后递归解析返回的schema,支持嵌套$ref场景 if (schema.$ref) { const reqParams = { id: schema.id }; const { data: remoteSchema } = await $axios.get(schema.$ref, { params: reqParams }); return this.parseJsonToObject(remoteSchema); } // 基础类型直接返回对应配置 if (['string', 'number', 'boolean'].includes(schema.type)) { return schema.title; } const parsedResult: Record<string, any> = {}; const props = schema.properties || {}; // 用for...of替代forEach,保证每个属性的异步解析完成后再赋值 for (const [propKey, propConfig] of Object.entries(props)) { parsedResult[propKey] = await this.parseJsonToObject(propConfig); } return parsedResult; }
使用注意事项
- 调用该解析方法时必须加
await,因为整个解析过程包含异步请求:const schemaObj = await this.parseJsonToObject(rootSchema) - 如果业务中存在循环$ref引用(如A引用B、B引用A),需要新增一个Set缓存已请求过的ref地址,遇到已缓存的地址直接跳过,避免无限递归死循环。
- 如果需要解析数组类型(
type: 'array')的schema,额外增加分支判断,对schema.items字段递归解析即可。
内容的提问来源于stack exchange,提问作者Avinash Rajendran
相关产品推荐
相关产品推荐

