分步从数据库中获取项目并按顺序执行操作

fetch items from database in steps and perform operations sequentially

我有一个包含很多项目的数据库,我需要对每个项目执行一个操作 items.Unfortunatly,我必须按顺序 运行 这些操作并延迟每个操作以避免速率限制。

我的方法不会等待前面的操作完成,我最终会受到速率限制。我必须更改什么才能使其按顺序 运行?

  setInterval(async () => {
      await this.processQueue();
    }, 1500)

 private async processQueue() {
    try {
      //Only 3 requests per second allowed by the API so I only take 3 items from the database on every call
      const bids = await getRepository(Bid).find({ order: { created_at: "ASC" }, take: 3, skip: 0 })

      if (bids) {
        for (const bid of bids) {
          //check if active order exists
          const activeOrder = await this.accountService.hasActiveOrder(bid.tokenId, bid.tokenAddress, 0);

          if (!activeOrder) {
            //perform async functions with that db item
            const startTime = Date.now();
            await this.placeBid(bid);
            //delete from database so the next call to processQueue does not return the same itemsagain
            await getRepository(Bid).delete({ id: bid.id })
            const endTime = Date.now() - startTime;
          }
        }
      }

    } catch (error) {
      console.error("TradingService processQeueu", error.message);
    }
  }

您的间隔计时器与 processQueue 函数正在完成的工作之间没有协调。将 async 函数作为其回调传递给 setInterval 具有误导性且无用; setInterval 不使用回调的 return 值,因此它 return 的承诺不用于任何事情。

相反,最小的改变是使用等待processQueue完成的东西,也许是一系列setTimeout回调:

function processAndWait() {
    processQueue().then(() => setTimeout(processAndWait, 1500));
    // (Normally I'd have a `catch` call as well, but `processQueue`
    // ensures it never rejects its promise)
}

请注意,队列处理完毕后等待 1500 毫秒。如果 API 允许每秒最多调用 3 次,那可能有点矫枉过正了。您可能 trim 到 1000 毫秒。

或者如果这是 class 中的方法(public 或私有):

processAndWait() {
    processQueue().then(() => {
        this.queueTimer = setTimeout(() => this.processAndWait(), 1500);
    });
    // (Normally I'd have a `catch` call as well, but `processQueue`
    // ensures it never rejects its promise)
}

请注意,我添加了一些将计时器句柄保存到 属性 的内容,因此您可以使用 clearTimeout(this.queueTimer) 来停止进程。