首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >你能把UrlFetchApp转换成应用程序脚本中的承诺吗?

你能把UrlFetchApp转换成应用程序脚本中的承诺吗?
EN

Stack Overflow用户
提问于 2020-10-24 16:40:23
回答 1查看 788关注 0票数 3

UrlFetchApp.fetch同步执行,使执行速度变慢。是否有可能将UrlFetchApp转化为承诺?

我一直在想这个办法:

  1. 返回HTTPResponse.getContent()作为承诺,并将所有urls添加到队列中。
  2. 将它们的执行推迟到调用getContent().then()之后。
  3. 当调用任何urls的getContent()时,使用fetchAll获取所有结果并清除队列。

你觉得这种方法有什么问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-24 17:45:27

从理论上讲,这种方法似乎是合理的,特别是因为已知的异步执行

  • .fetch()调用是实际获取的地方。因此,对UrlFetchApp对象的任何钩子都应该在fetch调用之前插入。
  • 您可以使用Proxy object连接到UrlFetchApp上的.fetch调用,以返回带有thenable对象的虚拟HTTPResponse
  • 然后,如问题中所述,在.getContent调用上使用.getContent
  • 但是,请注意,应用程序脚本中的承诺可能会执行,也可能不会像发布注释#1至#4中所说的那样异步执行。然而,这不应该是您的方法的一个问题。

考虑到承诺的微妙性质和不明确的文档,最好在任何生产环境中避免它们。实现批处理请求的更好方法是对thenable对象使用普通的自定义函数:

代码语言:javascript
运行
复制
function test() {
  /**
   * @description Batches requests until then is called on a response
   *   and fetches all batched requests
   * @return {object} A then object, which when called fetches the batch
   * @param {string} url Url to fetch
   * @param {object} options Options to fetch. See UrlFetchApp.fetch
   */
  const fetchAsBatch = function fetch(requests, url, options) {
    options.url = url;
    requests.add(options);
    return {
      then: func => {
        const responses = func(UrlFetchApp.fetchAll([...requests]));
        requests.clear();// clear current batch
        return responses;
      },
    };
  }.bind(this, new Set());

  const successHandlerLogger = responses => {
    /*Do something with all responses*/
    console.log(responses.map(response => response.getContentText()));
  };
  fetchAsBatch('https://example.com', { method: 'get' });
  fetchAsBatch('https://httpbin.org/post', { method: 'post' }).then(
    successHandlerLogger
  );
  fetchAsBatch('https://google.com', {}).then(successHandlerLogger);
}

代码语言:javascript
运行
复制
function test() {
  /**
   * @description Batches requests until then is called on a response
   *   and fetches all batched requests
   * @return {object} A then object, which when called fetches the batch
   * @param {string} url Url to fetch
   * @param {object} options Options to fetch. See UrlFetchApp.fetch
   */
  const fetchAsBatch = function fetch(requests, url, options) {
    options.url = url;
    requests.add(options);
    return {
      then: func => {
        const responses = func(UrlFetchApp.fetchAll([...requests]));
        requests.clear();
        return responses;
      },
    };
  }.bind(this, new Set());

  const successHandlerLogger = responses => {
    /*Do something with all responses*/
    console.log(responses.map(response => response.getContentText()));
  };
  fetchAsBatch('https://example.com', { method: 'get' });
  fetchAsBatch('https://httpbin.org/post', { method: 'post' }).then(
    successHandlerLogger
  );
  fetchAsBatch('https://google.com', {}).then(successHandlerLogger);
}
/*Mock urlfetchapp library to return requests without fetch*/
const UrlFetchApp = {
  fetchAll: requests =>
    requests.map(request => ({
      getContentText: () => request,
    })),
};

test();

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64515736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档