gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 02:45:01 25 4
gpt4 key购买 nike

我对 Javascript 的异步世界还比较陌生。我的函数对 Firebase Admin SDK 进行了一些调用,并对第三方 API 进行了一些提取请求。该功能有效,但每隔一段时间我就会收到 socket hang up 错误。我基本上想等到所有 await 函数完成后再发送 res.end(),但看起来我在使用 async/await 方面做错了什么>.

我的函数完成(看起来它命中了 res.end())但它一直在继续:

enter image description here

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

enter image description here

以下是我构建代码的方式:

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();
}

最佳答案

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

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

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

现在为了等待所有函数循环的结束,您可以实现自己的 promise 链。查看您的代码,等待的最后一个 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

关于javascript - 使用 Google Cloud Functions Node.JS 等待多个异步函数的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66180561/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com