【问题标题】:Asynchronous results (Promise) vs AJAX异步结果(Promise)与 AJAX
【发布时间】:2014-07-16 17:34:45
【问题描述】:

所以我使用 Play 作为我的 MVC 框架。我的 Web 应用程序只是调用 Postgres 数据库以将数据提供给视图。我目前在视图中使用 AJAX 来获取数据。我想有时数据库在发送数据时会有点滞后,所以我会使用 AJAX 来允许加载视图中的其他元素。

现在我的问题是,既然我已经在视图中使用了 AJAX,我应该在控制器中使用 Promises 吗?如果我使用 Promises 会有什么不同吗?我没有足够的经验来弄清楚视图和控制器中的异步操作如何影响我的 Web 应用程序。我的直觉是,AJAX 操作对于每天点击 100 到 150 次的 Web 应用程序来说已经足够了。

您对此有何见解?

【问题讨论】:

  • 由于您的数据存储是 Postgres,因此您的数据库调用已经是同步的。将它们包装在承诺/期货中不会有太大的不同。此外,除非您确定这是您的瓶颈,否则可能不值得优化。
  • 嗯,很好,因为我忘了考虑数据库。但是假设每个 AJAX 调用都建立了自己的数据库连接。这在某种程度上不是“异步”的吗?
  • 不,因为您仍在阻塞线程并消耗资源。
  • 感谢您的意见@Ryan

标签: ajax model-view-controller asynchronous playframework playframework-2.0


【解决方案1】:

非阻塞 I/O 和 Promises 的重点不在于速度或延迟,而在于 better use of resources。默认情况下,Play 为每个 CPU 内核提供一个线程。当您在这些线程上执行的所有工作都非常快时,这非常有效 - 也就是说,您避免了昂贵的计算并仅使用非阻塞 I/O。但是,所有 JDBC 调用都是同步的,因此它们会长时间阻塞少数可用线程,并且如果您有足够的流量,任何新请求都必须排队,从而增加页面的加载时间。

因此,对于 DB 调用,您是否应该使用 Promises(或者更准确地说是单独的线程池)与您是在初始页面加载还是通过 AJAX 调用进行这些 DB 调用无关。这只是关于您期望有多少流量,您有多少线程,以及您将使用每个线程多长时间。对于大多数应用程序,最佳实践是在单独的线程池上运行 DB 调用,这样它们就不会阻塞主工作线程。

例如在application.conf中配置一个线程池(即ExecutionContext)如下:

  akka {
    actor {
      db-context {
        fork-join-executor {
          parallelism-factor = 20.0
          parallelism-max = 200
        }
      }
    }
  }

然后在您的数据库代码中使用该线程池:

  def dbLookup(someId: Int): Future[SomeDbValue] = {
    val dbExecutionContext = Akka.system.dispatchers.lookup("db-context")
    Future {
      // DB code to fetch SomeDbValue
    }(dbExecutionContext)
  }

完整说明请参见Play Framework Thread Pools,更多背景信息请参见Play Framework: async I/O without the thread pool and callback hell

【讨论】:

  • 完美。你的文章非常有见地,只是简单地浏览了一下。期待阅读其余部分。 Play 的文档几乎列出了我脑海中的问题。谢谢你。
猜你喜欢
  • 2013-04-24
  • 2017-01-09
  • 2019-04-12
  • 2018-04-13
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-17
相关资源
最近更新 更多