javascript - 在递归函数中正确处理二维值数组

标签 javascript google-apps-script google-sheets

我正在 Apps 脚本中实现自定义函数。

为了允许该函数在 Google 表格中用作数组公式,我使用了以下函数模板:

function myfunction(input) {
  if (input.map) {                // Test whether input is an array.
    return input.map(myfunction); // Recurse over array if so.
  } else {
    // Handle individual values here...
  }
}

这样做允许自定义函数接受一个范围作为二维数组形式的输入,然后返回一个可以溢出到适当单元格中的二维数组。 This is documented here.

但是对于下面的代码,我没有使用“input”,而是使用“url”,我认为这是问题的根源。我产生了错误:Attribute provided with no value: url (line 5)

function getRedirect(url) {
  if (url.map) {
    return url.map(getRedirect);
  } else {
    var response = UrlFetchApp.fetch(url, {'followRedirects': false, 'muteHttpExceptions': false});
    var redirectUrl = response.getHeaders()['Location']; // undefined if no redirect, so...
    var responseCode = response.getResponseCode();
    if (redirectUrl) {                                   // ...if redirected...
      var nextRedirectUrl = getRedirect(redirectUrl);    // ...it calls itself recursively...
      Logger.log(url + " is redirecting to " + redirectUrl + ". (" + responseCode + ")");
      return nextRedirectUrl;
    } else {                                               // ...until it's not
      Logger.log(url + " is canonical. (" + responseCode + ")");
      return url;
    }
  }  
}

我该怎么做才能解决这个问题?

最佳答案

我怀疑您没有正确处理不是有效 URL 的值。假设您的脚本没有更多内容,第 5 行包含 UrlFetchApp.fetch() 调用,我认为这是错误的来源。

您应该在 UrlFetchApp.fetch() 调用之前和期间执行额外的错误检查。这是一个修改后的实现,展示了我的建议:

function getRedirect(url) {
  if (url.map) {
    return url.map(getRedirect);
  }

  // Return an empty string if url contains a non-string value or an empty string.
  if (typeof url != 'string' || url == '') {
    return '';
  }

  // Enclose the UrlFetchApp.fetch() call in a try/catch() block...
  try {
    var response = UrlFetchApp.fetch(url, {
        'followRedirects': false,
        'muteHttpExceptions': false
    });
  } catch(e) {
    // And return an empty string if the call fails
    // (e.g. if provided a non-empty, non-URL string).
    return '';
  }

  var redirectUrl = response.getHeaders()['Location'];
  var responseCode = response.getResponseCode();
  if (redirectUrl) {
    var nextRedirectUrl = getRedirect(redirectUrl);
    return nextRedirectUrl;
  }
  return url;
}

一些注意事项:

  • try/catch block 之前执行尽可能多的错误检查。在调用 UrlFetchApp.fetch() 之前处理无效输入要快得多。调用 fetch 方法并等待它失败可能会花费明显更长的时间,尤其是在处理大范围时。
  • 我删除了日志记录语句以使示例更加简洁,但谨慎的做法是记录错误情况和/或返回指出错误的字符串而不是空字符串。
  • 变量的名称是不相关的(即 inputurl)
  • 我删除了多余的 else block ,因为 return 语句无论如何都会结束函数的执行。

关于javascript - 在递归函数中正确处理二维值数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58740290/

相关文章:

google-apps-script - 需要帮助为 SpreadsheetApp(Google Apps 脚本)创建 GMAIL Pub/Sub 通知服务

hyperlink - 使用JS将单元格中的链接复制到另一个工作表时保留超链接URL

javascript - 错误: "You have an error in your SQL syntax; near ' '' at line 1"

javascript - 操作电子表格数据以实现可视化

javascript - 循环遍历 Google App 脚本并设置多个不连续的值

javascript - 如何更新 fullcalendar.js 中的开始时间(!)

javascript - document.all 和 document.forms[0] 的区别

javascript - 如果 REGEX 表达式的条件与使用 Google 应用程序脚本输入的单元格不匹配,如何拒绝输入

javascript - 实现多个组合框只会产生一个下拉按钮

javascript - 'innerText' 能防止 XSS 吗?