【问题标题】:fetch items from database in steps and perform operations sequentially逐步从数据库中获取项目并按顺序执行操作
【发布时间】:2022-01-19 17:38:23
【问题描述】:

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

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

  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);
    }
  }

【问题讨论】:

    标签: node.js typescript typeorm


    【解决方案1】:

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

    相反,最小的变化是使用确实等待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 允许每秒最多三个调用,这可能是矫枉过正。您可能可以将其修剪为 1000 毫秒。

    或者如果这是一个类中的方法(公共或私有):

    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) 来停止该过程。

    【讨论】:

    • 那么我需要做什么才能多次处理和等待?据我了解,您的代码只执行一次 processQueue。
    • @BitQueen - 是什么让你这么想?查看then 处理程序的代码。它为processAndWait设置了一个定时回调,它将处理队列,等待它完成,并设置一个定时回调到processAndWait,这将......这就是为什么我称之为“a setTimeout 回调的链式系列".
    • 哦,我很抱歉。谢谢你的推荐,我会试试的!
    • 我已经改成这个私有 processAndWait() { this.processQueue().then(() => setTimeout(this.processAndWait, 1200));然后在 update() this.processAndWait() 中调用它会返回错误“processQueue is not a function”
    • @BitQueen - 见this question's answers(可能还有this one),当setTimeout 调用该方法时,你没有保留this
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 2017-03-10
    相关资源
    最近更新 更多