Javascript 使用Google Cloud functions Node.JS等待多个异步函数的正确方法
我对Javascript的异步世界比较陌生。我的函数对Firebase Admin SDK进行一些调用,并对第三方API进行一些获取请求。该函数可以工作,但每隔一段时间我就会收到一个Javascript 使用Google Cloud functions Node.JS等待多个异步函数的正确方法,javascript,node.js,asynchronous,async-await,google-cloud-functions,Javascript,Node.js,Asynchronous,Async Await,Google Cloud Functions,我对Javascript的异步世界比较陌生。我的函数对Firebase Admin SDK进行一些调用,并对第三方API进行一些获取请求。该函数可以工作,但每隔一段时间我就会收到一个套接字挂起错误。我基本上想等到所有等待函数完成后再发送res.end(),但就使用async/await而言,我似乎做错了什么 我的函数完成(看起来像是点击了res.end()),但它仍在继续: 奇怪的是,相同执行ID的错误出现在以下执行ID中: 以下是我构建代码的方式: exports.myFunction =
套接字挂起
错误。我基本上想等到所有等待函数完成后再发送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();
}
因此,您有一些嵌套的承诺,实际上不会等待所有承诺都完成,您的结构如下:
| 1 exports.myFunction
| | 1 ordersRef.once
| | | 1 deleteRef.once
| | | 2 shopInfoRef.once
| | | | 1 updateInventory.updateInventory
| | | | 2 deleteProduct.deleteProduct
| 1 exports.myFunction
| | 1 awaiter
| | - 1 ordersRef.once
| | - | 1 deleteRef.once
| | - | 2 shopInfoRef.once
| | - | | 1 updateInventory.updateInventory
| | - | | 2 deleteProduct.deleteProduct
| | ----------> 3 awaiter.resolve
事实上,您的异步函数将只等待第一个较低级别的承诺,因此例如deleteRef.once
将只等待shopInfoRef.once
,而不等待updateInventory.updateInventory
。这意味着您的顶级exports.myFunction
将只等待ordersRef。一旦解析,将忽略其余部分。这些数字表示承诺的执行顺序,因为您对所有承诺都使用wait,所以我们在同一级别上没有承诺(没有重复的数字)
现在,为了等待所有功能周期的结束,您可以实现自己的承诺链。查看您的代码,等待的最后一个承诺是deleteProduct.deleteProduct
,因为当您达到这一点时,由于所有wait
关键字,任何其他承诺都会得到解决
exports.myFunction=async(req,res)=>{
//解析主体。。。
//如果是封闭式订单
if(json.hasOwnProperty('closed_at')){
让等待者=新承诺((解决)=>{
//从orders目录获取order对象
等待订单ref.once(“值”),异步函数(快照){
var orderResponseObj=snapshot.val();
//用orderResponseObj做些事情
//**在此之前调用res.end()**
等待deleteRef.once(“值”),异步函数(快照){
var deletesponseobj=snapshot.val();
//对delete对象执行一些操作
});
//从商店目录获取对象
等待shopInfoRef.once(“值”),异步函数(快照){
var firebaserensesponseobj=snapshot.val();
等待updateInventory.updateInventory();//对第三方API执行一些获取请求
等待deleteProduct.deleteProduct();//对第三方API执行另一个获取调用
resolve();//我们将resolve放在链的最后一点
});
});
});
//等待异步函数的执行
//等待“等待者”的“解决”功能
//承诺是被召唤的,所以在链条的最后
等待等待者;
}
//终止云功能
res.end();
}
显然,您可以将代码压缩为等待新承诺(resolve=>{…})
这样的形式,但为了清晰起见,我将两句话分开
新结构的结果如下:
| 1 exports.myFunction
| | 1 ordersRef.once
| | | 1 deleteRef.once
| | | 2 shopInfoRef.once
| | | | 1 updateInventory.updateInventory
| | | | 2 deleteProduct.deleteProduct
| 1 exports.myFunction
| | 1 awaiter
| | - 1 ordersRef.once
| | - | 1 deleteRef.once
| | - | 2 shopInfoRef.once
| | - | | 1 updateInventory.updateInventory
| | - | | 2 deleteProduct.deleteProduct
| | ----------> 3 awaiter.resolve