首页 > 解决方案 > GAS UrlFetchApp.fetchAll 将所有响应合并到一个 JSON 响应中

问题描述

我有一个返回大 JSON 的请求:

function fetchDataFromApi(request, params) {

var url = 'https://someurl/get-records?' + 
              'school=someSchool&' +
              'year=';
    var yearToday = parseInt(new Date().getFullYear());

    var requests = [];
    for (var i = 2011; i < yearToday; i++)
    {
      requests.push(url + i);
    }

    return JSON.parse(UrlFetchApp.fetchAll(requests).map(function(e) { return e.getContentText()}));

}

我按年对它进行了切片,这样 UrlFetchApp 就不必处理 50MB 的 blob 限制。但是它会引发错误:

 Exception details: InternalError: Array length 53673928 exceeds supported capacity limit.

但是当我尝试访问响应的每个元素时,例如

JSON.parse(UrlFetchApp.fetchAll(requests)[0].getContentText()

...它工作正常。

关于导致问题的原因的任何想法?

我还尝试将所有响应分成单独的请求。

var responses = []
for (var i = 2011; i < yearToday; i++)
{
  var request = url + i;
  responses.push(UrlFetchApp.fetch(request).getContentText());
}

var json = JSON.parse([].concat.apply([], responses));
return json;

但是在 Google Data Studio 中抛出了这个错误:

Array length 68522537 exceeds supported capacity limit.

标签: javascriptgoogle-apps-scriptgoogle-data-studiourlfetch

解决方案


如果您想解决 50 MB 的限制,这不是要走的路

即使您映射响应,您也必须先完整检索它。另见这篇文章

因此,您可能希望(并且需要)为每个请求执行单独的fetch调用 - 从而将响应 blob 的大小拆分为单独的 blob。

    var responses = [];
    for (var i = 2011; i < yearToday; i++)
    {
      var request = url + i;
      responses.push(JSON.parse(UrlFetchApp.fetch(request).getContentText()));
    }
    return responses;

根据每个请求响应的大小,您也可以分批进行 - 例如一次fetchAll处理 2-3 个请求。


推荐阅读