我正在 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
方法并等待它失败可能会花费明显更长的时间,尤其是在处理大范围时。 - 我删除了日志记录语句以使示例更加简洁,但谨慎的做法是记录错误情况和/或返回指出错误的字符串而不是空字符串。
- 变量的名称是不相关的(即
input
与url
) - 我删除了多余的
else
block ,因为return
语句无论如何都会结束函数的执行。
关于javascript - 在递归函数中正确处理二维值数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58740290/