使用 redis 管理亚马逊翻译

Managing amazon translation with redis

我必须使用来自亚马逊的 aws 管理一个 json 的翻译并将缓存保存在 redis 中。

async function translateSomething(trans, p1, sourceLan, targetLan) {
  var paramsName = {
    Text: p1,
    SourceLanguageCode: sourceLan,
    TargetLanguageCode: targetLan,
  };

  let myPromise = () =>
    new Promise((resolve, reject) => {
      trans.translateText(paramsName, function (err, data) {
        if (err) throw err;
        if (data) {
          console.log("translated", data.TranslatedText);
          resolve(data.TranslatedText);
        }
      });
    });

  let res = await myPromise();
  return res;
}
// and this function to check if the value is in the menu or not

function storeOrFound(p1, value, sourceLan, targetLan) {
  return redisClient.get(p1, async (err, result) => {
    if (err) console.log("err", err);
    if (result) {
      console.log("element is already in cache", JSON.parse(result).val);

      let tmp = JSON.parse(result).val;

      return tmp;
    } else {
      var translate = new AWS.Translate({ region: AWS.config.region });

      let val = await translateSomething(
        translate,
        value,
        sourceLan,
        targetLan,
      );

      redisClient.setex(
        p1,
        3600,
        JSON.stringify({ source: "Redis Cache", val }),
      );

      return val;
    }
  });
}
// and after i execute the query of the db i use this function to check if is present or not on the db or not

something().then((doc) => {
  for (let i = 0; i < doc.items.length; i++) {
    const menuRedisKeyName = `name:${doc.items[i].name}21`;
    doc.items[i].name = storeOrFound(
      menuRedisKeyName,
      doc.items[i].name,
      menuLang,
      targetLan,
    );
  }
  console.log("JSON", JSON.stringify(doc));
  res.end(JSON.stringify(doc));
});

问题是方法 storeOrFound returns true or false (因为 return redisClient.get return true or false 无论对象是否存在。任何管理这个问题的想法?同样在控制台上,我看到 console.log(" element is already in cache"..) 打印在最后。我错过了同步的什么吗?

你可能想要这样的东西。

  • translateSomethingcheckCache return 承诺,因此您可以在 async/await 代码中轻松使用它们。
  • getFromCacheOrTranslate 将这两个包装在一个异步函数中。

代码中还有一些未来添加的 TODO 注释。

function translateSomething(translate, text, sourceLan, targetLan) {
  return new Promise((resolve, reject) => {
    translate.translateText(
      {
        Text: text,
        SourceLanguageCode: sourceLan,
        TargetLanguageCode: targetLan,
      },
      function (err, data) {
        if (err && !data) {
          reject(err);
          return;
        }
        console.log("translated", data.TranslatedText);
        resolve(data.TranslatedText);
      },
    );
  });
}

/**
 * Promisified version of `redisClient.get()`.
 */
function checkCache(key) {
  return new Promise((resolve, reject) => {
    redisClient.get(key, (err, result) => {
      if (err) {
        reject(err);
      }
      resolve(result);
    });
  });
}

async function getFromCacheOrTranslate(text, sourceLan, targetLan) {
  const key = `translate:${sourceLan}:${targetLan}:${text}`; // TODO: hash the text here for a shorter cache key
  let result = await checkCache(key);
  if (result) {
    // result was in cache, return it
    return JSON.parse(result);
  }
  // Otherwise save it to the cache and return it
  const translate = new AWS.Translate({ region: AWS.config.region });
  result = await translateSomething(translate, text, sourceLan, targetLan);
  redisClient.setex(key, 3600, JSON.stringify(result)); // Async result ignored here
  return result;
}

something().then(async (doc) => {
  // TODO: this could use `Promise.all` to do this in parallel
  for (let i = 0; i < doc.items.length; i++) {
    doc.items[i].name = await getFromCacheOrTranslate(
      doc.items[i].name,
      menuLang,
      targetLan,
    );
  }
  console.log("JSON", JSON.stringify(doc));
  res.end(JSON.stringify(doc));
});