Node.js调用Google Translate API递归翻译JSON异步问题求解
问题根因
代码提前触发写入的核心原因是异步链路没有打通,具体存在4个关键错误:
- 递归遍历嵌套JSON时,遇到对象类型调用
iterateAndTranslate没有加await,嵌套层级的翻译任务不会被外层等待,函数会直接返回未完成的Promise。 - 读取文件的方法中调用异步的
iterateAndTranslate时,没有等待其执行完毕,靠固定时长的setTimeout赌执行时间,文件大小、网络波动都会导致逻辑失效。 - Node.js fs API混用:
writeFileSync是同步阻塞方法,本身不返回Promise也不接收回调参数,原写法属于API误用。 for...in循环未声明key变量,存在全局作用域污染隐患。
修正后可直接运行的代码
const fs = require('fs/promises') // 直接使用Promise版fs API,避免同步异步混用 const {Translate} = require('@google-cloud/translate').v2 require('dotenv').config() process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0 const credentials = JSON.parse(process.env.credentials) const translate = new Translate({ credentials, projectId: credentials.project_id, }) // 递归翻译,所有异步操作都加await保证执行顺序 const iterateAndTranslate = async (data) => { for(const key in data) { if (typeof data[key] === 'object' && data[key] !== null) { // 递归调用必须加await,等待子层级全部翻译完成 await iterateAndTranslate(data[key]) } else{ data[key] = await translateText(data[key], 'fr') } } } // 翻译方法 const translateText = async (text, targetLanguage) => { try { let [response] = await translate.translate(text, targetLanguage) return response } catch (error) { console.log(`翻译字段失败,原文:${text},错误:`, error) return text // 翻译失败返回原文本,避免字段值变成0导致格式异常 } } // 主流程:读文件->翻译->写文件,全链路await控制顺序 const start = async () => { try { // 读文件也用异步API,避免阻塞 const fileContent = await fs.readFile('...\\locale\\en.json', 'utf-8') const data = JSON.parse(fileContent) // 等待全部翻译完成 await iterateAndTranslate(data) // 翻译完成后再写入 const outputFileName = 'C:\\test\\test.json' await fs.writeFile(outputFileName, JSON.stringify(data, null, 4)) console.log('翻译写入完成!') } catch (error) { console.log('执行出错:', error) } } // 启动流程 start()
关键修改点说明
- 全链路使用
async/await打通异步流程:递归调用、翻译调用、文件读写都加await保证执行顺序,彻底移除不稳定的setTimeout延迟逻辑。 - 统一使用
fs/promises提供的Promise版文件API,避免同步API阻塞事件循环,同时解决原代码同步异步API混用的问题。 - 翻译失败时返回原文本而不是0,避免原JSON字段值异常。
- 循环内的
key加const声明,避免全局变量污染。 - 去掉全局的
data变量,所有数据在流程内传递,避免全局状态带来的不可预期问题。
内容的提问来源于stack exchange,提问作者letsCode
相关产品推荐
相关产品推荐

