Google apps script 文件夹迭代器继续令牌递归循环

Google apps script 文件夹迭代器继续令牌递归循环,google-apps-script,Google Apps Script,感谢你们帮助thusfar在TeamDrive中设置这个递归循环。以下是我到目前为止的情况。此时我唯一的问题是,在我指定的团队驱动器中有成千上万个文件夹。因此,我认为我需要获得一个延续令牌,以使脚本运行时间超过6分钟。然而,我完全不知道在脚本中的什么地方可以获取或存储令牌。我认为最简单的方法是每1-10次迭代运行一次令牌以确保安全。以下是我目前的代码: function generateFolderTree() { try { var rootFolder = DriveApp.

感谢你们帮助thusfar在TeamDrive中设置这个递归循环。以下是我到目前为止的情况。此时我唯一的问题是,在我指定的团队驱动器中有成千上万个文件夹。因此,我认为我需要获得一个延续令牌,以使脚本运行时间超过6分钟。然而,我完全不知道在脚本中的什么地方可以获取或存储令牌。我认为最简单的方法是每1-10次迭代运行一次令牌以确保安全。以下是我目前的代码:

function generateFolderTree() {

  try {

    var rootFolder = DriveApp.getFolderById('xxxxxxxxxxxxxxx');
    var rootFolderName = rootFolder.getName();
    var rootsFolders = rootFolder.getFolders();

    //var ss = SpreadsheetApp.create("Emptyfolderslist"+ Math.floor(Date.now() / 1000));
    var ss = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxxx');

    var sheet = ss.getSheets()[0];
    sheet.appendRow(["Parent Folder", "Folder URL", "Folder Name", "", "folder count", "file count"]);

    while( rootsFolders.hasNext()) {

      var currentFolder = rootsFolders.next()          
      var currentFolderFiles = currentFolder.getFiles();
      var currentFolderFolders = currentFolder.getFolders();
      var folderscount = 0;
      var filescount = 0;

      while( currentFolderFiles.hasNext()){
        filescount ++;
        currentFolderFiles.next();
      }

      while( currentFolderFolders.hasNext()){
        folderscount++;
        currentFolderFolders.next();
      }

      var path = '';
      var parentfldrs = currentFolder.getParents();
      while( parentfldrs.hasNext()) {
        path = path + " - " + parentfldrs.next().getName();
      }

      sheet.appendRow(["'============================="]);
      sheet.appendRow([path, currentFolder.getUrl(), currentFolder.getName(), "", folderscount, filescount]);

      getChildFolders(currentFolder, ss); 
    }
  } catch (e) {
    Logger.log(e.toString());
  }
}


function getChildFolders(aFolder, ss) {

  var childFolders = aFolder.getFolders();
  var filesInFolder = aFolder.getFiles();
  var sheet = ss.getSheets()[0];

  var foldercount = 0;
  var filecount = 0;
  var childFolder = '';
  var parentFolders = '';
  var loop = 0;

  while( childFolders.hasNext()){
    foldercount = 0;
    filecount = 0;
    childFolder = childFolders.next();

    var subFolders = childFolder.getFolders();
    var subFiles = childFolder.getFiles();

    while( subFolders.hasNext()) {
      foldercount++;
      subFolders.next();
    }

    while( subFiles.hasNext()) {
      filecount++;
      subFiles.next()
    }

    var parentfldrs = childFolder.getParents();

    while( parentfldrs.hasNext()) {
      parentFolders = parentfldrs.next().getName();
    }

    sheet.appendRow([parentFolders, childFolder.getUrl(), "'----", childFolder.getName(), foldercount, filecount]);

    getChildFolders(childFolder, ss);
  }
}
我在这里阅读了其他几个链接,其中包含使用搜索的类似问题,如下所示:


在对Google Apps脚本的执行调用之间存储动态项的唯一方法是使用或。 通常不会在执行之间更改的静态项(例如电子表格id或对特定CacheService的引用)可以安全地存储为全局变量

如果您计划在几分钟/小时内使用延续令牌,我建议您使用
CacheService
。如果您需要在超过6小时后保留延续令牌以供使用,则需要使用
PropertiesService
(因为6小时是某些内容放入缓存服务后在缓存服务中停留的最长时间)

您需要添加程序逻辑,以便能够从循环中的任意点恢复。如果您确保只输入将在剩余时间内完成的循环,则从任意点恢复将更容易,例如,将开始时间存储在变量中(
var start=new Date().getTime()
),并在开始新循环之前检查剩余时间(
if(new Date().getTime()-start
)。如果没有足够的时间(例如1米、30秒等),则应保存状态并退出。如果不保存状态并干净地退出,则会复制数据,因为某些内部循环会重复

最简单的开始是存储根级迭代器的
continuationToken
,如对链接问题的回答所示:

要继续,首先检查该键的缓存/属性,如果不存在,则从头开始。您可能需要在缓存/属性中存储其他值(并且类似地使用存储的值):


如果您想要现成的模板,可以将其用于递归文件夹和暂停/恢复功能。查看类似的问题


基本上,这是通过存储一个对象数组来完成的,这样我们就知道在每个文件夹迭代器和文件迭代器中从何处恢复。。。但是你有没有试着用你从阅读中学到的东西呢?可能是重复的,我试了4个小时的多种方法。但他们似乎都过早地结束了剧本。一个人甚至会在经历一个循环之前结束它,一个循环之后结束它。当我让脚本创建一个电子表格而不是修改时,它会在继续过程中创建数百个电子表格,但没有其他函数。。。如果有帮助的话,我可以发布一些版本,但它们一点也不干净
...
while( rootFolders.hasNext() {
  // If more than 2/3 the execution time has been used, bail out.
  if( new Date().getTime() - start > 200 * 1000)
    return;

  ...

  getChildFolders(currentFolder, ss);

  // Store the continuation token for the maximum time (6h).
  if( rootFolders.hasNext())
    cache.put("ROOT_CONTINUE_TOKEN", rootFolders.getContinuationToken(), 21600);
  else
    cache.remove("ROOT_CONTINUE_TOKEN");
}
...
var cache = CacheService.getScriptCache();
function generateFolderTree() {
  var cached = cache.get("someKey");
  var folderIterator;
  if(cached) {
    folderIterator = DriveApp.continueFolderIterator(cached);
    /* code for initializing a resumed iteration */
  }
  else {
    /* code for initializing an iteration from scratch */
  }

  /* code for iterating */
}