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