node脚本批量跑翻译接口 生成国际化json

1、引入 node 的 fs模块:文件系统操作的核心模块,它提供了一系列的方法来读取、写入、创建、删除文件和目录等
2、引入 接口请求 axios库
const fs = require("fs");
const axios = require("axios");

3、读取JSON文件

function readJSONFile(filePath) {
  try {
    // "utf8" 参数确保返回字符串而非 buffer
    const data = fs.readFileSync(filePath, "utf8");
    return JSON.parse(data);
  } catch (error) {
    console.error("Error reading file:", error);
    return null;
  }
}

4、提取 国际化 JSON 对象中的值

function extractValues(jsonObj) {
  const values = [];
  for (const key in jsonObj) {
    if (jsonObj.hasOwnProperty(key)) {
      values.push(jsonObj[key]);
    }
  }
  console.log("提取JSON对象中的值", values)
  return values;
}

5、调用翻译接口   这里批量跑接口 用到的是 promise.allSettled
这里涉及promise 的一些常用方法的差异和使用场景
Promise.all 、Promise.race、Promise.any、Promise.allSettled

相同点:
1、这四个方法都是接受一个 可迭代对象(如:数组、Set),可迭代对象中的元素通常是Promise实例
2、这四个方法都会返回一个新的Promise对象;可以用.then 或者 async/await语法来处理


不同点:
    Promise.all
        完成条件: 所有传入的Promise都成功兑现
        结果处理:返回一个兑现的 Promise,其结果是一个数组,数组元素按传入 Promise 的顺序排列,对应每        个 Promise 的兑现值。若有一个 Promise 被拒绝,新 Promise 会立即被拒绝,原因是第一个被拒绝的 Promise 的原因

    Promise.race
         完成条件:传入的 Promise 中有一个率先敲定(兑现或拒绝)
          处理结果:返回的 Promise 会以第一个敲定的 Promise 的相同状态和结果进行敲定。

    Promise.any
        完成条件:传入的 Promise 中有一个成功兑现
        处理记过:返回一个兑现的 Promise,结果是第一个成功兑现的 Promise 的值。若所有 Promise 都被拒绝,新 Promise 会被拒绝,原因是一个 AggregateError 对象,包含所有被拒绝的原因。

    Promise.allSettled
        完成条件:所有传入的 Promise 都已敲定(兑现或拒绝)
        处理结果:	返回一个兑现的 Promise,结果是一个数组,数组中的每个元素是一个对象,包含 status('fulfilled' 或 'rejected')和 value(兑现值)或 reason(拒绝原因)。


使用场景
    Promise.all :适用于所有异步操作都必须成功完成的场景,例如在一个页面加载时需要同时获取多个 API 的数据,只有当所有数据都成功获取时页面才能正常渲染。

    Promise.race:适用于多个异步操作竞争,只需要其中一个操作的结果的场景,例如同时从多个服务器获取数据,只要有一个服务器返回结果就使用该结果。

    Promise.any:	适用于多个异步操作中只要有一个成功即可的场景,比如同时从多个镜像服务器下载文件,只要有一个下载成功就行。

    Promise.allSettled:适用于需要知道每个异步操作最终结果的场景,即使有些操作失败也不影响后续处理,比如同时上传多个文件,无论某个文件上传是否成功,都要记录所有文件的上传结果。

  

async function translateValues(values) {
  let translatedValues = {
    de: [],
    es: [],
    th: [],
  };
  const batchSize = 10;
  const batches = [];
  for (let i = 0; i < values.length; i += batchSize) {
    const batch = values.slice(i, i + batchSize);
    batches.push(batch);
  }
  const results = await Promise.allSettled(
    batches.map((batch) => {
      return axios
        .post(
          "请求地址",
          {
            access_token:"xxx",
            source_text: batch,
            target_language: ["de", "es", "th"],
          }
        )
        .then((response) => response.data.data.translate)
        .catch((error) => {
          console.log("接口错误", batch);
          // console.error("Error translating batch:", batch, error);
          // 若翻译出错,保留原内容
          return batch;
        });
    })
  );
  const translatedBatches = results.map((result) =>
    result.status === "fulfilled" ? result.value : result.reason
  );
  translatedBatches.map((item) => {
    if (Array.isArray(item)) {
      Object.keys(translatedValues).forEach((key) => {
        translatedValues[key] = [...translatedValues[key], ...item];
      });
    } else {
      Object.keys(item).forEach((key) => {
        translatedValues[key] = [...translatedValues[key], ...item[key]];
      });
    }
  });
  return translatedValues;
}

6、需要 替换JSON中的值

/**
 * 更新 JSON 对象中的值
 * @param {Object} jsonObj - 需要更新的 JSON 对象
 * @param {Array} translatedValues - 新的翻译值数组
 * @returns {Object} 更新后的 JSON 对象
 * @description 将传入的翻译值数组按顺序替换 JSON 对象中对应 key 的值
 */
function updateJSONValues(jsonObj, translatedValues) {
  const keys = Object.keys(jsonObj);
  for (let i = 0; i < keys.length; i++) {
    jsonObj[keys[i]] = translatedValues[i];
  }
  return jsonObj;
}

7、将替换完的JSON 写入 文件中

/**
 * 将 JSON 对象写入指定文件
 * @param {string} filePath - 文件路径
 * @param {Object} jsonObj - 要写入的 JSON 对象
 * @throws {Error} 写入文件失败时抛出错误
 */
function writeJSONFile(filePath, jsonObj) {
  try {
    // 将 JSON 对象格式化为带缩进(2空格)的字符串,提升可读性。
    const data = JSON.stringify(jsonObj, null, 2);
    fs.writeFileSync(filePath, data, "utf8");
    console.log("File updated successfully");
  } catch (error) {
    console.error("Error writing file:", error);
  }
}

8、主函数

/**
 * 主函数,用于处理 JSON 文件的翻译流程
 * 1. 读取中文源文件 zh_CN.json
 * 2. 提取需要翻译的值
 * 3. 调用翻译接口进行翻译
 * 4. 将翻译结果更新到原 JSON 结构中
 * 5. 将结果保存到不同的目标语言文件
 *
 * @async
 * @function main
 * @returns {Promise<void>}
 */
async function main() {
  const inputFilePath = "zh_CN.json";

  const inputJSON = readJSONFile(inputFilePath);
  if (inputJSON) {
    const values = extractValues(inputJSON);
    const translatedValues = await translateValues(values);
    for (let i in translatedValues) {
      const newTranslateValues = translatedValues[i];
      const updatedJSON = updateJSONValues(inputJSON, newTranslateValues);
      writeJSONFile(`结果/${i}.json`, updatedJSON);
    }
  }
}

9、node index.js 启动就行了

 
 
 
 

 

posted @ 2025-03-10 17:10  敲代码的树先生  阅读(63)  评论(0)    收藏  举报