使用缓存提高脚本速度

时间:2014-03-05 19:01:53

标签: javascript caching google-apps-script

我有一个脚本可以获取电子表格的所有值,并使用这些值在日历中创建条目。

但是,运行和超时需要很长时间。

由于没有足够的条目,它过去没那么久,但现在有足够的条目在它超时之前无法完成,所以我需要提高速度。

我认为它运行得如此之慢的原因是因为有一个循环贯穿电子表格的每一行,并且在每个循环结束时它都会写一个日历事件。我认为这会增加执行时间,因为它必须一遍又一遍地重新连接到日历。我认为这大大增加了执行时间。

我相信我可以通过缓存减少这一点,但我甚至没有丝毫的线索如何运作。

这是我的代码:

/**
 * Export events from spreadsheet to calendar
 */
function exportEvents() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var headerRows = 1;  // Number of rows of header info (to skip)
  var range = sheet.getDataRange();
  var data = range.getValues();
  var calId = "trhcom7eiadkcn39mg9d0hfceg@group.calendar.google.com";
  var cal = CalendarApp.getCalendarById(calId);
  for (i in data) {
    if (i < headerRows) continue; // Skip header row(s)
    var row = data[i];
    var date = new Date(row[9]);
    if (!(isValidDate(date))) continue; // Skip rows without a date
    var title = row[19]+" - "+row[3]+" - "+row[1]+" - "+row[2];
    var id = row[31];
    // Check if event already exists, delete it if it does
    try {
      var event = cal.getEventSeriesById(id);
      event.deleteEventSeries();
      row[31] = '';  // Remove event ID
    }
    catch (e) {
      // do nothing - we just want to avoid the exception when event doesn't exist
    }
    var newEvent = cal.createAllDayEvent(title, date).addEmailReminder(4320).addEmailReminder(60).addSmsReminder(4320).addSmsReminder(60).getId();
    row[31] = newEvent;  // Update the data array with event ID
  }
  i=0;
  for (i in data) {
    if (i < headerRows) continue; // Skip header row(s)
    var row = data[i];
    var date = new Date(row[13]);
    if (!(isValidDate(date))) continue; // Skip rows without a date
    var title = "Expected Pay Date: "+row[19];
    var id = row[32];
    // Check if event already exists, delete it if it does
    try {
      var event = cal.getEventSeriesById(id);
      event.deleteEventSeries();
      row[32] = '';  // Remove event ID
    }
    catch (e) {
      // do nothing - we just want to avoid the exception when event doesn't exist
    }
    date.setDate(date.getDate() + 12);
    var newEvent = cal.createAllDayEvent(title, date).addEmailReminder(4320).addEmailReminder(60).addSmsReminder(4320).addSmsReminder(60).getId();
    row[32] = newEvent;  // Update the data array with event ID
  }
  // Record all event IDs to spreadsheet
  range.setValues(data);
};

我正在尝试使用this page中的信息,但我甚至不知道从哪里开始。

缓存是存储在本地还是存储在服务器上?我该如何访问它?什么是钥匙,我在哪里找到它?我用什么网址?这最终会如何提高我的速度?

我觉得这很简单,但我不理解这个概念。

更新:在做了一些研究后,我不确定缓存可以帮助我,因为它不会获取需要很长时间而是创建数据的数据。

也许我应该试着想办法在循环结束时简单地将所有事件写入日历,但我不知道该怎么做。

1 个答案:

答案 0 :(得分:3)

你的问题包含很多问题,但你已经自己回答了几个...... ;-)这确实不是读表数据的问题(你已经使用getDataRange()以正确的方式解决了这个问题.getValues( ))但是事件创建的问题需要很长时间......

不幸的是,没有办法加快速度,我们唯一能做的就是缩小批量,然后让脚本每10分钟自动运行一次,直到所有事件都被创建。

没有什么比这更复杂了,这是一个显示过程的脚本:

function createEvents() {
  // check if the script runs for the first time or not,
  // if so, create the trigger and PropertiesService.getScriptProperties() the script will use
  // a start index to know were from it has to continue

  if(PropertiesService.getScriptProperties().getKeys().length==0){ 
    PropertiesService.getScriptProperties().setProperties({'startRow':0 });
    ScriptApp.newTrigger('createEvents').timeBased().everyMinutes(10).create();
  }
  // initialize all variables when we start 
  var startRow = Number(PropertiesService.getScriptProperties().getProperty('startRow'));

  var sheet = SpreadsheetApp.getActiveSheet();
  var headerRows = 1;  // Number of rows of header info (to skip)
  var range = sheet.getDataRange();
  var data = range.getValues();
  var calId = "trhcom7eiadkcn39mg9d0hfceg@group.calendar.google.com";
  var cal = CalendarApp.getCalendarById(calId);
  var counter = 0
  for (var i=tstartRow ; i < data.length ; i++) {
    counter++ ;
    if(counter == 30){ break }
    if (i < headerRows) continue; // Skip header row(s)
    var row = data[i];
    ...
    ... continue your own code 
   }
   // update the spreadsheet
   // if i== data.length then kill the trigger and eventually send yourself a message 
   // to tell you that the script has finished successfully .
   // killing the current trigger goes like this :
   var trigger = ScriptApp.getProjectTriggers()[0];
   ScriptApp.deleteTrigger(trigger);
祝你好运。