【问题标题】:How do I extend script execution time?如何延长脚本执行时间?
【发布时间】:2017-12-04 11:46:19
【问题描述】:

我有这个脚本可以从我的 Google 云端硬盘中删除所有 ._* 文件。但是有数百万个文件,脚本在 5 分钟左右后退出,并显示“超出最大执行时间”。

function TrashDotFiles() {
  var files = DriveApp.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    var name = file.getName();
    if (name.indexOf("._")==0) {
      console.log(name + " • trashed");
      file.setTrashed(true)
    }
  }
}

如何让这个脚本运行足够长的时间来扫描整个云端硬盘?

【问题讨论】:

  • 搜索类似问题。您不能延长时间,但可以使用触发器按部分处理它。

标签: google-apps-script google-drive-api


【解决方案1】:

一种可能的解决方法是在没有运行时间限制的模式窗口中运行纯 JavaScript 代码:

function onOpen()
{
  var ui = SpreadsheetApp.getUi();

  ui.createMenu('Trash dot files')
      .addItem('Run', 'openWindow')
      .addToUi();
}

function openWindow()
{
  var ui = SpreadsheetApp.getUi();

  // get template
  var template = HtmlService.createTemplateFromFile('deleteDriveFiles');

  // need to have next line of text somewhere (even commented out) to trigger correct scopes for script and token:
  // DriveApp.getFiles()

  // pass token
  template.data = {
    token: ScriptApp.getOAuthToken()
  };

  // get output html
  var html = template.evaluate();

  // show modal window
  ui.showModalDialog(html, 'Delete files from Drive');
}

[文件 - 新建 - Html 文件] deleteDriveFiles.html:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
  <script>

  // used for visual log
  function addParagraph(text)
  {
    var node = document.createElement('p');
    node.innerText = text;
    document.body.appendChild(node);
  }

  // for stats
  var totalProcessed = 0;
  var totalTrashed = 0;

  function reqListener(){
    // get response obj
    var res = JSON.parse(this.responseText);

    if (res.items && res.items.length)
    {
      // loop files
      for (var i = 0; i < res.items.length; i++)
      {
        var file = res.items[i];

        // delete file
        if (file.title.indexOf('._') == 0)
        {
          var xhr = new XMLHttpRequest();
          xhr.addEventListener('load', function(){
            // get response obj
            var res = JSON.parse(this.responseText);

            // sucessfully trashed
            if (this.status == 200)
            {
              totalTrashed++;
              addParagraph('Trashed '+res.title);
            }
          }.bind(xhr));
          xhr.open('POST', 'https://www.googleapis.com/drive/v2/files/'+file.id+'/trash');
          xhr.setRequestHeader('Authorization', 'Bearer <?=data.token?>');
          xhr.send();
        }
      }

      // for stats
      totalProcessed += res.items.length;
    }

    // get next page of results
    if (res.nextPageToken)
    {
      var xhr = new XMLHttpRequest();
      xhr.addEventListener('load', reqListener);
      xhr.open('GET', 'https://www.googleapis.com/drive/v2/files?trashed=false&pageToken='+res.nextPageToken);
      xhr.setRequestHeader('Authorization', 'Bearer <?=data.token?>');
      xhr.send();
    }
    // finished
    else
    {
      addParagraph('Finished. Processed total: '+totalProcessed+'. Trashed total: '+totalTrashed);
    }
  }

  var xhr = new XMLHttpRequest();
  xhr.addEventListener('load', reqListener);
  xhr.open('GET', 'https://www.googleapis.com/drive/v2/files?trashed=false');
  xhr.setRequestHeader('Authorization', 'Bearer <?=data.token?>');
  xhr.send();

  </script>
  </body>
</html>

保存代码更改并刷新电子表格网页后,您将看到新的菜单项:

点击运行开始处理文件。

结果:

【讨论】:

  • 实际上......它工作......但只检查 100 个文件。我想我需要以某种方式授权 API?
  • 是的,它检查 100 个文件,然后检查下 100 个文件,直到 Drive API 返回 nextPageToken。在最后的消息中,将有已处理文件的总数:“已完成。已处理总数:3377。已丢弃总数:2”
  • 这不是为我做的;它在 100 之后停止。始终“已处理的总数:100”
  • 它还向我显示了文件删除之前的统计信息,例如,请参阅i.imgur.com/2N0G18w.png
  • 我只在 Chrome 中测试过,你可以尝试在 Chrome 中运行它并检查开发者控制台是否有任何错误?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-25
相关资源
最近更新 更多