【问题标题】:Exception: Invalid argument: continuationToken例外:无效参数:continuationToken
【发布时间】:2021-11-24 15:57:48
【问题描述】:

我正在尝试使用来自this post 的“工作示例(线性迭代器)”来实现一个简单的延续令牌,但我不断收到“异常:无效参数:continuationToken”错误,不知道如何解决这个问题.

我尝试将 var userProperties 和 var continuationToken 从全局移动到我的 deleteFile() 中,但仍然不行。调试器还显示 userProperties 填充了数据,但 continuationToken 始终为空(在错误之前)。也不知道为什么它总是跳到 else 情况下失败,即使在第一次运行时也是如此。

const sheetID = "IDgoeshere"; //sheet with ids and user names 
const sheetName = 'Sheet1' //name of the sheet in the doc
const emailID = Session.getActiveUser().getEmail();
var userProperties = PropertiesService.getUserProperties();
var continuationToken = userProperties.getProperty('CONTINUATION_TOKEN');

function deleteFile() {
  const spreadsheet = SpreadsheetApp.openById(sheetID);
  const sheet = spreadsheet.getSheetByName(sheetName);
  const lastRow = sheet.getLastRow();
  const values = sheet.getRange(2, 4, lastRow - 1, 3).getValues();
  values.forEach((row, index) => {
    const owner = row[0];
    const id = row[2];
    if (continuationToken == null) {  
      if (emailID == row[1]) {
        try {
          var file = DriveApp.getFileById(row[2])
          if (file.isTrashed == true) {
            console.info('was trashed');
            row++;
          }
          else {
            file.setTrashed(true);
          }
        }
        catch (e) {
          console.info(`Unable to find file with id ${id}`);
        }
      }
      else {
        // not the first time, pick up where we left off
        var files = DriveApp.continueFileIterator(continuationToken); ***//errors out here***
      }
    }
    while (files.hasNext() && end.getTime() - start.getTime() <= maxTime) {
      var file = files.next();
      Logger.log(file.getName());
      end = new Date();
    }

    if (files.hasNext()) {
      var continuationToken = files.getContinuationToken();
      userProperties.setProperty('CONTINUATION_TOKEN', continuationToken);
    }
    else {
      // Delete the token
      PropertiesService.getUserProperties().deleteProperty('CONTINUATION_TOKEN');
    }
});
}

【问题讨论】:

  • 前一个迭代器从哪里继续? PropertiesService 不是迭代器。请将您的minimal reproducible example 简化为一个函数,以便我们更轻松地重现问题。您过度使用全局变量使代码难以理解。让我们更轻松,也许您会得到一些帮助。
  • 好问题:我不确定。我只是假设工作示例正在运行,并尝试将其应用到我的代码中。似乎它还没有完全工作。我应该从“userProperties.setProperty('CONTINUATION_TOKEN', continuationToken);”开始吗?类型行。我以前没有使用过延续令牌,TBH 我的编码也有很多不足之处。我一直在努力的另一个假设是脚本开始时有一个令牌,并将从那里开始。如果没有,并且需要设置一个,我不知道这一点。编辑:知道了,现在改写为 MRE。
  • 把它归结为我认为是一个很好的最小可重现示例。感谢您的提醒。

标签: google-apps-script google-sheets


【解决方案1】:

这是一个人为的例子:

function myfunk1(token) {
  const folder = DriveApp.getFolderById(gobj.globals.testfolderid);
  let files;
  if(token == null) {
    files = folder.getFiles();
  } else {
    Logger.log('get continuaton token')
    files = DriveApp.continueFileIterator(token);
  }
  while(files.hasNext) {
    let file = files.next();
    Logger.log(file.getName());
    if(!token ) {
      try {
        myfunk1(files.getContinuationToken())
      }
      catch{
        return;
      }
    }
  }
}

在此示例中,我只是中断了迭代器的处理,并使用延续令牌递归调用该函数一次。

【讨论】:

  • 好的,如果我正确地遵循了这一点: 1. 我应该能够为 const 文件夹分一个工作表,因为我正在操作的所有 ID 都在那个工作表中。2. 如果没有令牌,它应该开始执行我的 deleteFile(),对吗?(基本上将所有与执行用户的电子邮件地址匹配的项目标记为上表中的“已删除”) 3.“否则”它将查找最后一个留下的令牌执行那个用户?4.“当”它找到另一行fileID时,我可以getname或.setTrashed(true)吗?5.如果没有令牌,.getcontinuationtoken()并继续.setTrashed(true)
  • 好吧,我认为您不能用工作表替换文件夹。 DriveApp 与工作表无关,除了电子表格是文件这一事实。
  • 大概您有一些进程花费的时间超过了脚本可以运行的时间。所以你需要在它失败之前停止它,然后在短时间内重新启动它,但你希望在你结束的同一个地方恢复它。 DriveApp.continueFileIterator 将允许您这样做,只要您提供有效的 fileIterator 延续令牌。
  • 正确,我的文件 ID 比一次执行中的垃圾还多。所以,我试图弄清楚在哪里跟踪时间以及我应该多久更新一次令牌。我是否需要在 UserProperties 下的 PropertiesService 中设置令牌,然后在继续之前先检查那里?类似于:userProperties.setProperty('CONTINUATION_TOKEN', continuationToken);
  • 在您的情况下,我认为您真的不需要担心延续令牌,您只需要知道您在哪一行停止并在下一次迭代中从该行开始,是的,我想我' d 只是将其存储在 PropertiesService 中。
猜你喜欢
  • 1970-01-01
  • 2011-06-04
  • 1970-01-01
  • 2020-06-26
  • 1970-01-01
  • 1970-01-01
  • 2016-07-07
  • 2020-04-20
  • 2021-01-30
相关资源
最近更新 更多