[英]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.