无法从用户缓存的Google Apps脚本中检索对象

时间:2019-03-14 17:32:30

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

我在从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()函数,但是在那之后,我无法在第一段代码中从缓存中检索到它。我在做什么错了?

1 个答案:

答案 0 :(得分:0)

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

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函数,切换到Google表格容器文件,然后打开浏览器控制台。单击边栏按钮。检查您的Stackdriver日志-一切似乎都很好。

enter image description here

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

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对象之类的东西,这将导致函数参数未定义/丢失。