【问题标题】:Prevent overload due to Promise resolving防止因 Promise 解析而导致过载
【发布时间】:2017-09-26 01:36:31
【问题描述】:

我需要使用 mongoose 执行大量 findOneAndUpdate() 操作,因为无法批量执行原子操作。因此,我在 for 循环中创建了一个 promise 数组,之后将被解析。不幸的是,这需要大约 2-3 秒,在此期间我的 Express 应用程序无法处理任何新请求。

代码:

const promiseArray = []
for (let i = 0; i < 1500; i++) {
  const p = PlayerProfile.findOneAndUpdate(filter, updateDoc)
  promiseArray.push(p)
}
return Promise.all(promiseArray).then((values) => {
  // Process the values
})

问题:

如何避免我的 Express 应用程序在解决此承诺时对新请求完全没有响应?

更多上下文信息:

我正在尝试使用原子操作更新和返回许多文档,因此是大 for 循环。它基本上是选择一个文档并为此文档设置一个锁定。

【问题讨论】:

  • 该代码中没有任何内容解析任何这些承诺,它只是生成它们(假设合理猜测findOneAndUpdate 做了什么,因为它返回了一个承诺)。您是在询问创建承诺数组的延迟(这似乎不应该花费任何时间)或等待解决方案?如果是后者,您需要向我们展示更多上下文...
  • @T.J.Crowder 我添加了 then,我希望这是足够的上下文。我不认为 promise 数组的创建需要那么长时间。我确信(尽管我没有详细检查)解决 1500 个 findOneAndUpdate 操作需要 2-3 秒。
  • 您能否详细说明您想要实现的目标?在 HTTP 查询上对 DB 进行 1.5k 次查询表明架构存在问题。
  • 除非findOneAndUpdate 实际上做了很多同步操作,否则它不应该阻塞。这是一个很大的循环,这很可能就是问题所在。
  • @RistoNovik 我理解印象,但我需要做的是通过原子操作查找和修改多个文档,以便并发请求不会再次返回和修改同一个文档。跨度>

标签: javascript node.js express mongoose bluebird


【解决方案1】:

尝试使用 updatemulti 选项:

PlayerProfile.update(filter, updateDoc, { multi: true }, function(err, result) {
  // Do something
})

签名是:

Model.update(conditions, update, options, callback)

【讨论】:

  • 这不会返回我的案例所必需的更新文件。
  • 您可以使用 find 和相同的过滤器。
  • 那么它不再是原子的了,这也是必要的。我在原始线程中添加了更多上下文信息。
  • 文档建议为防止 MongoDB 多次插入同一个文档,请创建唯一索引并在更新时使用 upsert: true 选项。
  • 我没有插入。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-11
  • 2011-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多