5

我正在使用 Cloud Functions for Firebase 来:

  1. 从 api.ai 接收参数
  2. 调用第三方 API 并
  3. 回复 api.ai。

我对第三方 API 的调用使用了请求 Node.js 模块,并且包装getInfoFromApi()在 index.js 中的函数 ( ) 中。

我遇到的问题是辅助函数调用的执行始终需要 15-20 秒。注意:云函数本身在 400 毫秒范围内始终如一地完成其执行。

通过将简单的注释记录到控制台,我可以看到函数何时启动、何时调用辅助函数以及何时收到第三方的响应,所以我想我可以看到发生了什么。

大致来说,时间安排是这样的:

  • 0:云函数初始化
  • 400 毫秒:云功能完成
  • 16 秒:getInfoFromApi()函数被调用 (!)
  • 17s:第三方API返回结果

我的问题:

  • 调用辅助函数的延迟是否有明显的原因?这似乎不是由冷启动问题引起的,因为云功能迅速恢复活力,即使在重复调用后延迟也是一致的。
  • 使用“请求”节点模块是否会导致问题?是否有更好的模块来创建/管理来自云功能的 http 请求?

您可以在此处查看 index.js 的简化要点:https ://gist.github.com/anonymous/7e00420cf2623b33b80d88880be04f65

这是 Firebase 控制台的截图,显示了示例时间。注意:输出与上面的代码略有不同,因为我简化了上面的代码以帮助理解。 在此处输入图像描述

4

2 回答 2

1

getInfoFrom3rdParty()调用是一个异步事件。但是,您尚未从函数返回承诺,因此 Functions 不会等待异步事件完成。

在我看来,由于您返回未定义,因此该函数还假定它失败并重试。在重试过程中的某个时刻,异步事件可能在函数退出之前完成(即由于竞争条件而意外成功)。我在其他情况下也看到过类似的结果,即用户没有在其函数中返回承诺或值。

我无法从要点上看出您要做什么——它似乎实际上并没有对第三方结果做任何事情,而且可能不是您的用例的现实 mcve。但这样的事情可能是你想要的:

exports.getInfo = functions.https.onRequest((request, response) => {
  // ....

  // NOTE THE RETURN; MOST IMPORTANT PART OF THIS SAMPLE
  return getInfoFromThirdParty(...).then(() => {
    response.writeHead(200, {"Content-Type": "application/json"});
    response.end(JSON.stringify(payload));
  }).catch(e => /* write error to response */);
});

function getInfoFrom3rdParty(food) {
  reqObj.body = '{"query": "'+food+'"}';

  return new Promise((resolve, reject) => {
       mainRequest(reqObj, function (error, response, body) {
          // ....
          if( error ) reject(error);
          else resolve(...);
          // ....
       });
  });
}
于 2017-04-13T17:38:29.397 回答
0

根据我对云功能的经验,一旦“执行完成”标志完成,它将导致延迟(从 3 秒到 15 秒)。这会阻止剩余的执行并增加您的总响应时间。

为了克服这个问题,您可以尝试向您的 3rd 方调用放置一个 Promise,一旦它完成,然后执行结束函数的“response.send()”。

于 2018-01-19T08:47:49.130 回答