我的日常计划功能出现了这两个错误,我试图每天检查是否是发薪日,并将相应的金额添加到每个用户的债务中。
Error: Process exited with code 16
at process.on.code (invoker.js:271)
at process.emit (events.js:198)
at process.EventEmitter.emit (domain.js:448)
at process.exit (per_thread.js:168)
at Object.logAndSendError (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/logger.js:37)
at process.on.err (invoker.js:268)
at process.emit (events.js:198)
at process.EventEmitter.emit (domain.js:448)
at emitPromiseRejectionWarnings (internal/process/promises.js:140)
at process._tickCallback (next_tick.js:69)
和:
Error: 4 DEADLINE_EXCEEDED: Deadline exceeded
at Object.callErrorFromStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call.js:30)
at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client.js:175)
at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:341)
at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:304)
at Http2CallStream.outputStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:116)
at Http2CallStream.maybeOutputStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:155)
at Http2CallStream.endCall (/workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:141)
at Http2CallStream.cancelWithStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:457)
at Timeout.DeadlineFilter.timer.setTimeout (deadline-filter.js:59)
at ontimeout (timers.js:436)
这是我的功能:
将*作为函数从";firebase函数";;以管理员身份从";firebase管理员";;
/// Checks every day if the debt pay day is equal to the setting and add the corresponding amount to the debt
export const checkForMonthChange = functions.pubsub
.schedule("every day 00:00")
.onRun(async (context) => {
try {
const db = admin.firestore();
const dayOfMonth = admin.firestore.Timestamp.now().toDate().getDate();
const neighborhoods = await db.collection("_settings").get();
const promises = [];
neighborhoods.forEach(async (doc) => {
const dayToPay = doc.data().day_of_month_to_pay;
if (dayOfMonth === dayToPay) {
const neighborhoodToUpdateName = doc.ref.id;
const neighborhoodToUpdate = await db
.collection(neighborhoodToUpdateName)
.get();
neighborhoodToUpdate.forEach(async (neighbor) => {
const userPlan = await neighbor.data().plan;
const amountToAdd = (
await db
.collection("_settings")
.doc(neighborhoodToUpdateName)
.collection("payment_plans")
.doc(userPlan)
.get()
).data().monthly_pay;
console.log(userPlan);
console.log(amountToAdd);
promises.push(
neighbor.ref.update({
debt: neighbor.data()?.debt + amountToAdd,
})
);
});
}
});
if (Promise.all.length !== 0) {
console.log(`Debt Increased Day of Month: ${dayOfMonth}`);
return Promise.all(promises);
} else {
return null;
}
} catch (error) {
console.log(`Error in every day schedule: ${error}`);
}
});
我做错了什么?
编辑:我在控制台中看到这2个日志
console.log(userPlan);
console.log(amountToAdd);
提前感谢
在forEach lambda函数中使用await
不会按预期方式工作。它不会暂停循环的执行。按照现在的编写方式,forEach循环将立即执行多次,每个邻域执行一次。代码将继续检查promises
数组(在执行任何循环之前(,该数组将始终为空。
您需要确保您的代码返回一个promise,该promise只有在forEach循环中的所有异步工作实际完成后才能解析。请参阅另一个问题,以便对此进行全面讨论。这个问题是由于forEach接受一个声明为async的函数,该函数会立即返回promise。
或者,您可以避免使用forEach,而是使用在更大函数的异步上下文中运行代码的for循环,这样您就可以按照预期的方式使用wait。
for (const doc of neighborhoods.docs) {
// use await here to pause the entire function
}