【问题标题】:Can't retrieve object from user cache Google Apps Script无法从用户缓存 Google Apps 脚本中检索对象
【发布时间】:2019-03-14 17:32:30
【问题描述】:

我在从 Google Apps 脚本的用户缓存中检索对象时遇到问题。我没有得到 null,我只是得到一个空对象。我什至想知道该对象是否已正确保存到用户缓存中。非常感谢任何帮助。这是我到目前为止所拥有的......

此代码不起作用:

// global variable to access user cache
var cache = CacheService.getUserCache();

// the function to save to cache for an end-user
function saveToUserCache(dynamicObj) {
  Logger.log(dynamicObj); // the object displays here
  cache.putAll(dynamicObj, 300);
  Logger.log(cache.getAll(['test1', 'test2'])); // the object does not display here
}

这是从 .html 文件中调用的:

...
// Object being passed dynamically: 
var testObj = {'test1': "value1",'test2': "value2"};
google.script.run.withSuccessHandler(onSuccess).saveToUserCache(testObj);
...

此代码有效:

// global variable to access user cache
var cache = CacheService.getUserCache();

// object to pass into the function
var testObj = {'test1': "value1",'test2': "value2"};

// the function to save to cache for an end-user
function saveToUserCache() {
  Logger.log(testObj); // the object displays here
  cache.putAll(testObj, 300);
  Logger.log(cache.getAll(['test1', 'test2'])); // the object displays here
}

给出一些上下文...我需要使用第一段代码的原因是因为我使用withSuccessHandler() 从前端GUI 传递一个对象。如您所见,该对象在第一个 Logger 中显示良好,因此数据到达saveToUserCache() 函数,但在那之后,我无法从第一块代码的缓存中检索它。我做错了什么?

【问题讨论】:

标签: caching google-apps-script web-applications


【解决方案1】:

我无法使用以下客户端和服务器代码重现您的问题:

code.gs(服务器端)

function saveToUserCache(clientObject) {
  const cache = CacheService.getUserCache();
  const clientKeys = Object.keys(clientObject);

  console.log({message: "object from client code", clientObject: clientObject, user: Session.getTemporaryActiveUserKey()});
  cache.putAll(clientObject, 300);
  const values = cache.getAll(clientKeys);
  console.log({message: "Retrieved key values from client object", keys: clientKeys, values: values});
  return {"type": "user", values: values};
}

var testObject = {"script_test1": "script_value1", "script_test2": "script_value2"};
function saveNonParameterToUserCache() {
  const cache = CacheService.getUserCache();
  const scriptKeys = Object.keys(testObject);

  console.log({message: "global var object", testObject: testObject, user: Session.getTemporaryActiveUserKey()});
  cache.putAll(testObject, 300);
  const values = cache.getAll(scriptKeys);
  console.log({message: "Retrieved key values from test object", keys: scriptKeys, values: values});
  return {"type":"fixed", values: values};
}

function showSidebar() {
  const output = HtmlService.createHtmlOutputFromFile("usercachetest.html");
  SpreadsheetApp.getUi().showSidebar(output);
}

usercachetest.html(客户端)

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <button onclick="doit()">Click to run</button>
  </body>
  <script>
    function doit() {
      console.log("running doit");
      var clientObject = {"user_test1": "user_value1", "user_test2": "user_value2"};
      google.script.run.withSuccessHandler(onSuccess).saveToUserCache(clientObject);
      google.script.run.withSuccessHandler(onSuccess).saveNonParameterToUserCache();
    }
    function onSuccess(result) {
      console.log(result);
    }
    </script>
</html>

运行showSidebar函数,切换到谷歌表格容器文件,然后打开浏览器控制台。单击侧边栏按钮。检查您的 Stackdriver 日志 - 一切似乎都很好。

请注意,根据CacheService 的限制,放入Cache 的所有键和值都必须是字符串。一个好的做法是在缓存它们之前在值上使用JSON.stringify,然后在返回它们以供使用之前从缓存中JSON.parseing 检索到的项目(如果有的话)。例如:

function foo(inputObject) {
  if (!inputObject) return;
  const cacheable = Object.keys(inputObject).reduce(function (obj, key) {
    obj[key] = JSON.stringify(inputObject[key]);
    return obj;
  }, {});
  CacheService.get____Cache().putAll(cacheable, expiryTime);
  ...
}

还要特别注意不要传递 invalid types from client to server - 像 Date 这样的对象是不允许的,这将导致未定义/缺少函数参数。

【讨论】:

  • 叹息......你在我说完之后就发布了这个......它仍然没有解释对象如何传递我不起作用的代码的第一部分,在第一个 Logger.log。最重要的是,您通过说语法错误开始了之前的对话。现在,您只是重复了我所说的并将其发布为答案。
  • @alex 公平地说,我的第一条评论(现已删除)旨在指出您不能将对象 values 传递给缓存,即{"key1": { "subkey1": "value1" }}。要缓存对象,您必须先将它们字符串化:{"key1": "{\"subkey1\": \"value1\"}"},然后在检索后对其进行解析。 w.r.t 为什么你的第一个记录器工作而第二个失败,但不能重现,我只能建议CacheService 的实现在某些方面可能是异步的,因此写入密钥有延迟。来自 Cache 的读取可能是同步的 - 只有 Google 员工才能说。
  • 另外,在测试密钥检索时,请确保每次测试的密钥都不同,以免您在一次测试中读到之前测试中放置的密钥。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多