【问题标题】:How to stop a recursive setTimeout with an API call?如何通过 API 调用停止递归 setTimeout?
【发布时间】:2022-09-27 09:01:28
【问题描述】:

我有一个 NextJS 应用程序,它在服务器启动时运行递归 setTimeout。我需要创建一个可以启动和停止此循环的 API 端点(以便在生产中对其进行更多控制)。此循环用于处理从另一个 API 端点添加的数据库中的项目。

  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 的原因是因为在处理从 DB 检索到的项目时会发生许多错误。然而,这些错误可以通过等待几毫秒来解决。所以,下面这个模式的好处是,如果发生错误,循环会立即重新启动,并且不会出现错误,因为已经过了一个毫秒(这是由于并发问题——我们暂时忽略这个) .

为了尝试启动和停止这个循环,我有一个简单地调用 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 循环也会继续进行。为什么不选择更改标志?

    标签: javascript node.js next.js settimeout


    【解决方案1】:

    您尝试过的内容可以在常规网页中使用,因为 loopFlag 变量将在全局(窗口)范围内。

    Next.js 不以相同的方式共享全局范围。因此,您需要使用React Context 来共享对变量的访问。

    【讨论】:

      猜你喜欢
      • 2019-10-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-18
      • 2021-02-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多