【问题标题】:Why does this Firebase Cloud Function function produce the error 'Error: function crashed out of request scope Function invocation was interrupted.'为什么此 Firebase Cloud Function 函数会产生错误“错误:函数崩溃超出请求范围函数调用被中断。”
【发布时间】:2019-11-28 16:29:03
【问题描述】:

我有一个 Firebase 云功能,每天在股市开市时触发一次。似乎在 20% 的时间运行时会产生错误。

错误说:'错误:函数崩溃超出请求范围函数调用被中断。'

export async function cleanIntraweek() {
  console.log(`cleanIntraweek() started`)

  const min_date_key = moment().tz("America/New_York").subtract(7, 'day').format()

  console.log(`min_date_key: ${min_date_key}`)

  //helper async function to grab some data
  const enabled_stock_keys = await FirebaseObjectFetchService.getStockKeys(true)

  const fetch_intraweek_dataset_promises: Promise<any>[] = []
  const clear_data_promises: Promise<any>[] = []

  for (const stock_key of enabled_stock_keys) {
    const fetch_intraweek_dataset_promise =
      db
        .ref(`charts/${stock_key}/intraweek_v3`)
        .orderByKey()
        .endAt(min_date_key)
        .once("value")
        .then((snapshot) => {
          snapshot.forEach((child_snapshot) => {
            const clear_data_promise = child_snapshot.ref.remove()
            clear_data_promises.push(clear_data_promise)
            return false
          });
        })
    fetch_intraweek_dataset_promises.push(fetch_intraweek_dataset_promise)
  }

  console.log("waiting on fetch_intraweek_dataset_promises")
  await Promise.all(fetch_intraweek_dataset_promises)

  console.log("waiting on clear_data_promises")
  await Promise.all(clear_data_promises).then(() => {console.log("cleanIntraweek() finished")})

  return null
}

我不记得当我的云功能在 Node 6 引擎上运行时出现此错误。从 Node 8 引擎(当前)恢复到 Node 6 引擎并不是一个解决方案,因为 Firebase Cloud Functions 将在一年内取消对 Node 6 引擎的支持。

最近一次错误运行的日志是:

我见过this post,但据我所知,在函数返回之前,我没有任何未等待的承诺。

【问题讨论】:

    标签: typescript firebase async-await google-cloud-functions


    【解决方案1】:

    此错误通常意味着您运行了一些异步代码,在函数应该完全完成后引发了执行。这意味着您实际上并没有正确处理函数中的所有承诺。问题似乎在这里发生:

        .then((snapshot) => {
          snapshot.forEach((child_snapshot) => {
            const clear_data_promise = child_snapshot.ref.remove()
            clear_data_promises.push(clear_data_promise)
            return false
          });
        })
    

    您有一个 Promise 回调,它异步创建更多 Promise 以删除子节点。但是,这里没有任何东西可以保证clear_data_promises 将在之后等待承诺列表之前被完全填充。换句话说,await Promise.all(clear_data_promises) 可以在保证完全填充 clear_data_promises 之前执行,因为 forEach lambda 本身不会阻塞每个操作的结果。

    您要做的是确保上面的 then 回调返回一个 Promise,该 Promise 跟踪 forEach labmda 中的所有内部 Promise。这将使fetch_intraweek_dataset_promise 承诺只有在所有从属工作完成后才会解决。类似的东西:

        .then((snapshot) => {
          const clear_data_promises = []
          snapshot.forEach((child_snapshot) => {
            const clear_data_promise = child_snapshot.ref.remove()
            clear_data_promises.push(clear_data_promise)
            return false
          });
          return Promise.all(clear_data_promises)
        })
    

    那么您以后就不必等待该数组了。这一切都将通过fetch_intraweek_dataset_promises 解决。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-28
      • 2018-01-16
      • 2017-01-26
      • 2019-01-08
      • 2016-02-03
      • 1970-01-01
      相关资源
      最近更新 更多