繁体   English   中英

使用 Google Cloud Functions Node.JS 等待多个异步函数的正确方法

[英]Proper way to await multiple async functions with Google Cloud Functions Node.JS

我对 Javascript 的异步世界比较陌生。 我的 function 对 Firebase 管理员 SDK 进行了一些调用,并对第三方 ZDB974238DZ08A3 进行了一些获取请求。 function 工作,但每隔一段时间我就会收到一个socket hang up错误。 我基本上想等到所有 await 函数完成后再发送res.end() ,但看起来我在使用async/await方面做错了。

我的 function 完成(看起来像命中res.end() )但它继续:

在此处输入图像描述

然后奇怪的是,来自相同执行 ID 的错误出现在以下执行 ID 中:

在此处输入图像描述

这是我构建代码的方式:

exports.myFunction = async (req, res) => {

    // parse the body...

    // if it's a closed order 
    if (json.hasOwnProperty('closed_at')) {

        // get order object from orders directory
        await ordersRef.once("value", async function(snapshot) {
            var orderResponseObj = snapshot.val();

            // do some stuff with orderResponseObj

            // ** res.end() CALLED BEFORE THIS HAPPENS **
            await deleteRef.once("value", async function(snapshot) {
                var deleteResponseObj = snapshot.val();
                // do some stuff with the delete object
            });

            // get object from shop directory
            await shopInfoRef.once("value", async function(snapshot) {
                var firebaseResponseObj = snapshot.val();

                await updateInventory.updateInventory(); // do some fetch request to 3rd party API

                await deleteProduct.deleteProduct(); // do another fetch call to 3rd party API
            });
        });
    }
    // terminate the cloud function
    res.end();
}

所以你有一些嵌套的承诺,实际上不会等待所有承诺完成,你的结构是这样的:

|   1 exports.myFunction
|   |   1 ordersRef.once
|   |   |   1 deleteRef.once
|   |   |   2 shopInfoRef.once
|   |   |   |   1 updateInventory.updateInventory
|   |   |   |   2 deleteProduct.deleteProduct

事实上,您的异步函数只会等待第一个较低级别的承诺,例如deleteRef.once只会等待shopInfoRef.once ,而不是等待updateInventory.updateInventory 这意味着您的顶级exports.myFunction将只等待ordersRef.once解析,忽略rest。 数字表示承诺的执行顺序,因为您对所有承诺都使用等待,所以我们在同一级别上没有 promise 一起触发(没有重复的数字)。

现在,为了等待所有 function 周期结束,您可以实现自己的承诺链。 查看您的代码,等待的最后一个 promise 是deleteProduct.deleteProduct ,因为当您到达该点时,由于所有await关键字,任何其他 promise 都已解决。

exports.myFunction = async (req, res) => {

    // parse the body...

    // if it's a closed order 
    if (json.hasOwnProperty('closed_at')) {
     let awaiter = new Promise((resolve) => {
        // get order object from orders directory
        await ordersRef.once("value", async function(snapshot) {
            var orderResponseObj = snapshot.val();

            // do some stuff with orderResponseObj

            // ** res.end() CALLED BEFORE THIS HAPPENS **
            await deleteRef.once("value", async function(snapshot) {
                var deleteResponseObj = snapshot.val();
                // do some stuff with the delete object
            });

            // get object from shop directory
            await shopInfoRef.once("value", async function(snapshot) {
                var firebaseResponseObj = snapshot.val();

                await updateInventory.updateInventory(); // do some fetch request to 3rd party API

                await deleteProduct.deleteProduct(); // do another fetch call to 3rd party API

                resolve(); // we put resolve in the very last point of the chain
            });
        });
      });

      // await make the execution of your async function
      // wait until the "resolve" function of our "awaiter"
      // promise is called, so at the very last of the chain
      await awaiter;
    }
    // terminate the cloud function
    res.end();
}

显然,您可以以await new Promise(resolve => {... })之类的形式收缩代码,但为了清楚起见,我将这两个句子分开。

新结构结果如下:

|   1 exports.myFunction
|   |   1 awaiter
|   |   -   1 ordersRef.once
|   |   -   |   1 deleteRef.once
|   |   -   |   2 shopInfoRef.once
|   |   -   |   |   1 updateInventory.updateInventory
|   |   -   |   |   2 deleteProduct.deleteProduct
|   |   ----------> 3 awaiter.resolve

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM