【问题标题】:Resolving a promise when wanted在需要时兑现承诺
【发布时间】:2022-01-04 17:56:05
【问题描述】:

我想不断地从网站同步数据,但我只有 300 个电话/15 分钟。因此,我认为我可以将我所有的同步请求(大约 1000 个)放入一个数组中,然后每 15 分钟解决其中的 300 个,直到请求数组为空,然后重新开始。但是,当我执行以下操作时:

  let requests = []
  params = 'invoice-items?invoice_id='
  let positions = null
  for (const invoice of invoices) {
    requests.push(new Promise(async (resolve, reject) => {
      positions = await getBillomatData(params + invoice.id, null, 0, null)
      await updateDatabase(positions, models.billomat.Position)
    }))
  }

  console.log(requests[0])
  await requests[0]
  console.log(requests[0])

只要我在 requests[0] 处等待请求,它就会执行所有请求,并且我会超出调用限制。

【问题讨论】:

  • 承诺执行器会立即运行,无论您是否、在何处以及何时等待承诺。只是在需要它们之前不要构造承诺,而是在循环本身中等待(睡眠)。
  • 正如@Bergi 提到的,您必须异步构建您的承诺。换句话说,您每 3 秒建立一次承诺。然后它可能会或可能不会变得更加复杂,具体取决于您的期望。有些承诺可能需要不到 3 秒的时间来解决,有些可能需要更长的时间。因此,时间尺度上的响应重叠可能会发生,例如在从服务器获得更新鲜的状态之后获得旧状态,这基本上是另一个问题。

标签: javascript node.js api asynchronous


【解决方案1】:

所有异步调用都会立即执行,因为 JavaScript 会在处理完每个调用后立即执行所有代码。 await 等待结果,不等待执行。

您需要使用bottleneck 等工具来限制您的请求。

每 15 分钟处理 300 个 1000 个请求将需要一个小时才能完成。这是保持节点作业无所事事运行的很长时间。

一个基本的基本限制器可能会跟踪您想要在外部文件或数据库中发出的所有请求,然后使用 cron 作业每 15 分钟执行一次 JavaScript 代码以处理另外 300 个请求。如果没有其他请求,您的应用程序可能会终止。但是,只要 cron 作业继续运行,它就会每 15 分钟唤醒并运行一次。

【讨论】:

  • 非常感谢,我试过瓶颈,它就像一个魅力
【解决方案2】:

最简单的方法(虽然没有优化)是

  • 批量调用 300 次
  • 执行一批并等待所有问题都解决后再继续下一批
let batch = []
// imagine urls is a array of url of 900 items
urls.map(async (url)=>{
  
  batch.push(somePromiseFuctionToDoTheApiCall(url))
  if(batch.length >= 300){
    await Promise.all(batch)
    // sleep is a promisified settimeout function, ref: https://stackoverflow.com/a/56520579/3359432
    await sleep(calculateTimeToWaitBeforeProceedingToNextBatch)
    batch = []
  }

})
// there might be some leftovers at the end of batch you should process them also

如果您可以使用库并停止重新发明轮子,请查看lodash.chunkbluebird.mapbluebird.eachbluebird.delay

【讨论】:

  • 问题是,代码在整个网站的一个脚本中运行,所以如果我睡到接下来的 15 分钟。在那段时间我无法使用该网站。
  • 请看参考链接,这是一个promisified settimeout函数。它是非阻塞的!
  • @RobinJehn 这不是真的。您仍然可以在请求处于休眠状态时使用该网站
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-21
  • 1970-01-01
  • 1970-01-01
  • 2018-03-27
  • 2015-05-20
相关资源
最近更新 更多