Javascript 函数在所有异步工作完成之前结束
所以我有一个功能,可以检查订单是否24小时有效,如果是这种情况,我会向用户发送通知,但它似乎并没有完成所有用户的执行,相反,它只返回一些用户,而其他一些用户不返回,我想我在返回承诺时遇到了问题,我不是javascript方面的专家,我也不太了解正在发生的事情,有时,如果一个文档的设备被视为空,而不是继续处理其他用户文档,我就不会尝试处理所有文档Javascript 函数在所有异步工作完成之前结束,javascript,firebase,google-cloud-firestore,google-cloud-functions,Javascript,Firebase,Google Cloud Firestore,Google Cloud Functions,所以我有一个功能,可以检查订单是否24小时有效,如果是这种情况,我会向用户发送通知,但它似乎并没有完成所有用户的执行,相反,它只返回一些用户,而其他一些用户不返回,我想我在返回承诺时遇到了问题,我不是javascript方面的专家,我也不太了解正在发生的事情,有时,如果一个文档的设备被视为空,而不是继续处理其他用户文档,我就不会尝试处理所有文档 exports.rememberToFinishOrder = functions.pubsub.schedule('every 3 minutes')
exports.rememberToFinishOrder = functions.pubsub.schedule('every 3 minutes').onRun(async (context) => {
var db = admin.firestore();
const tsToMillis = admin.firestore.Timestamp.now().toMillis()
const compareDate = new Date(tsToMillis - (24 * 60 * 60 * 1000)) //24 horas
let snap = await db.collection('orders').where("timestamp","<",new Date(compareDate)).where("status", "in" ,[1,2,4,5,6]).get()
if(snap.size > 0){
snap.forEach(async(doc) => {
const userId = doc.data().uid
let userSnap = await db.collection('user').doc(userId).get()
const deviceToken = userSnap.data().deviceToken
const payload = {
notification: {
title: "¿ Did you received your order ?",
body: "We need to know if you have received your order",
clickAction: "AppMainActivity"
},
data: {
ORDER_REMINDER: "ORDER_REMINDER"
}
}
console.log("User: "+doc.data().uid)
return admin.messaging().sendToDevice(deviceToken,payload)
});
}
});
有时,当在某些用户中devicetoken为空时,它将完成此函数的执行,而不是继续到下一个用户,而且它也不会为我的订单集合中的所有用户完成此函数,它将执行某些操作,而不执行某些操作,这应该是一个原子操作,可以更改该集合中的所有内容,不仅仅是一些文件
exports.rememberToFinishOrder = functions.pubsub.schedule('every 3 minutes').onRun(async (context) => {
var db = admin.firestore();
const tsToMillis = admin.firestore.Timestamp.now().toMillis()
const compareDate = new Date(tsToMillis - (24 * 60 * 60 * 1000)) //24 horas
let snap = await db.collection('orders').where("timestamp","<",new Date(compareDate)).where("status", "in" ,[1,2,4,5,6]).get()
if(snap.size > 0){
snap.forEach(async(doc) => {
const userId = doc.data().uid
let userSnap = await db.collection('user').doc(userId).get()
const deviceToken = userSnap.data().deviceToken
const payload = {
notification: {
title: "¿ Did you received your order ?",
body: "We need to know if you have received your order",
clickAction: "AppMainActivity"
},
data: {
ORDER_REMINDER: "ORDER_REMINDER"
}
}
console.log("User: "+doc.data().uid)
return admin.messaging().sendToDevice(deviceToken,payload)
});
}
});
发生了什么事?就像安德烈斯米贾尔斯所说的,你没有正确地履行承诺吗。 当您执行几个异步调用时,我建议使用Promise.all函数,该函数将等待所有承诺完成后再继续
exports.rememberToFinishOrder = functions.pubsub.schedule('every 3 minutes').onRun(async (context) => {
const db = admin.firestore();
const messaging = admin.messaging();
const tsToMillis = admin.firestore.Timestamp.now().toMillis()
const compareDate = new Date(tsToMillis - (24 * 60 * 60 * 1000)) //24 horas
const snap = await db.collection('orders').where("timestamp","<",new Date(compareDate)).where("status", "in" ,[1,2,4,5,6]).get()
let allPromises = [];
if(snap.size > 0){
snap.forEach((doc) => {
const userId = doc.data().uid;
allPromises.push(db.collection('user').doc(userId).get().then(userSnapshot => {
const userData = userSnapshot.data();
const deviceToken = userData.deviceToken;
if (userData && deviceToken) {
const payload = {
notification: {
title: "¿ Did you received your order ?",
body: "We need to know if you have received your order",
clickAction: "AppMainActivity"
},
data: {
ORDER_REMINDER: "ORDER_REMINDER"
}
}
console.log("User: "+doc.data().uid)
return messaging.sendToDevice(deviceToken,payload)
} else {
return;
}
}));
});
}
return Promise.all(allPromises);
});
编辑:
在发送通知之前,我添加了一个检查,以查看userData上是否存在deviceToken。我在另一个问题中给出了模式,您可以在此处应用相同的模式。如果你要使用forEach,你需要使用Promise.all来等待所有的承诺得到解决,否则,你可以使用for的方法有一致的方法吗?你是什么意思?你的错误是你没有正确处理承诺。你能帮我解决这个问题吗?嘿,Lunke,非常感谢你的回答,我会马上测试。一旦我有超过500份订单,我想我需要批量操作,你能帮我更新这个代码,让它在500个操作的批上运行吗?或者批处理只用于写操作?thanksBatches仅用于云Firestore的设置、更新和删除操作。请参阅以了解有关批次的更多信息。