【问题标题】:Asynchronous initialization of Firebase Functions [closed]Firebase 函数的异步初始化 [关闭]
【发布时间】:2021-05-12 01:30:46
【问题描述】:

我必须在我的函数启动时做一些异步工作,例如从 Google Secrets Manager 中获取秘密并根据这些秘密初始化客户端对象。我应该如何构造我的代码,以便我的函数异步初始化,并且可以访问已初始化的对象而无需等待它们?

【问题讨论】:

    标签: node.js firebase google-cloud-functions serverless


    【解决方案1】:

    如果不遇到竞争条件,就无法保证在触发函数之前初始化已经完成。 await 几乎是 somePromise.then(() => /* next bit of code */) 的语法糖,并且是非阻塞(如果你 await 某些东西,其他代码仍然可以执行,只是当前函数会暂停)。

    虽然您可以在其他语言中使用 while 循环来等待某个任务在另一个线程上完成,但 JavaScript 是单线程的,这样的 while 循环会阻止您的初始化代码运行。您需要使用回调或Promise 才能正确执行此操作。在这两个选项中,我会选择Promise 方法。这将允许您调用await init(),并且如果您将承诺缓存在init() 中,它可能在您需要使用该函数时已经完成,它将立即返回结果。这为您省去了处理包含所需数据的对象的生命周期管理、编写代码以检查它是否完成、处理初始化中的任何错误以及未来您的头疼的麻烦。

    async function _initDoTheWork() {
      /*
       * Take care of any async initialization here,
       * and return any result as applicable
       */
    
      const app = firebase.initializeApp();
      return { app }; // just as an example
    }
    
    /** 
     * Starts the initialization function, but
     * caches its promise to reuse in future calls
     */
    function initDoTheWork() {
      if (!initDoTheWork.promise) {
        initDoTheWork.promise = _initDoTheWork();
      }
      return initDoTheWork.promise;
    }
    
    // trigger async work now
    // ignore result, but trap errors so you don't get an Unhandled Rejection Exception
    initDoTheWork()
      .catch((err) => {
        // you could do nothing here, but I'd log the error somewhere
        console.error("Pre-initialization reported an error", error)
      });
    
    export async function doTheWork() { // the actual function to be exported
      const { app } = await initDoTheWork();
    
      const db = app.firestore();
    
      // do stuff with app & db
    }
    
    /**
     * Force reinitialization of doTheWork()
     * 
     * Note: Errors must be handled by the caller.
     */
    doTheWork.reinitialize = async function reinitialize() {
      initDoTheWork.promise = _initDoTheWork();
      return initDoTheWork.promise;
    }
    

    【讨论】:

    猜你喜欢
    • 2015-11-05
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多