我有一个NextJS应用程序,在服务器启动时运行一个递归的setTimeout。我需要创建一个API端点,可以启动和停止这个循环(在生产环境中更好地控制它)。该循环用于处理从另一个API端点添加的数据库中的项目。
我使用setTimeout而不是setInterval的原因是在处理从数据库检索得到的项目时可能会发生许多错误。然而,通过等待几毫秒可以解决这些错误。因此,以下模式的好处是如果发生错误,循环立即重新开始,并且错误不会出现,因为经过了一毫秒(这是由于并发问题造成的——暂时忽略这个问题)。
我有一个端点来尝试启动和停止这个循环,只需调用loopFlagSwitch函数。
问题是,即使调用了这个端点,setTimeout循环仍然在继续。为什么它没有注意到标志的变化呢?
import { clearTimeout } from "timers";
var loopFlag = true;
export function loopFlagSwitch(flag: boolean) {
loopFlag = flag;
}
export async function loop() {
try {
// Retrieve all unprocessed transactions
const unprocessedTransactions = await prisma.transaction.findMany({
take: 100,
where: { status: "UNPROCESSED" },
});
// Loop through transactions and do stuff
for (const transaction of unprocessedTransactions) {
//stuff
}
} catch (e) {
// handle error
}
if (loopFlag === true) {
setTimeout(loop, 1000); //if flag changes, this will stop running
}
}
if (require.main === module) {
loop(); // This is called when server starts, but not when file is imported
}
我使用setTimeout而不是setInterval的原因是在处理从数据库检索得到的项目时可能会发生许多错误。然而,通过等待几毫秒可以解决这些错误。因此,以下模式的好处是如果发生错误,循环立即重新开始,并且错误不会出现,因为经过了一毫秒(这是由于并发问题造成的——暂时忽略这个问题)。
我有一个端点来尝试启动和停止这个循环,只需调用loopFlagSwitch函数。
import { NextApiRequest, NextApiResponse } from "next";
import { loopFlagSwitch } from "services/loop";
async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
loopFlagSwitch(req.body.flag);
} catch (error) {
logger.info({ error: error });
}
}
export default handler;
问题是,即使调用了这个端点,setTimeout循环仍然在继续。为什么它没有注意到标志的变化呢?
req.body
是否为空对象或未定义等。可能是因为您没有使用正确的body解析器或者没有在API中发送正确的“Content-Type”头部,导致req.body.flag
始终返回未定义。 - ibrahim tanyalcin