multithreading - 如何在 future 中包装 Web Worker 响应消息?

标签 multithreading scala asynchronous web-worker scala.js

请考虑一个在浏览器中运行的 scala.js 应用程序,它由一个主程序和一个 Web Worker 组成。

主线程通过传递包含方法名称和调用它们所需的参数的消息,将长时间运行的操作委托(delegate)给 Web Worker。 Worker 将方法返回值以响应消息的形式传递回主线程。

简单来说,该程序抽象了 Web 工作线程消息传递,以便主线程中的代码可以使用惯用的异步 Scala 语法调用工作线程中的方法。

因为 Web Worker 不会以任何方式将消息与其响应关联起来,所以抽象依赖于注册表(一个中间对象),它控制每个跨上下文方法调用以将调用与结果关联起来。这个单例也可以绑定(bind)回调函数,但是有没有办法用 future 而不是回调来实现这一点?

如何在此注册表上构建抽象,以允许程序员将其与 Scala 中的标准异步编程结构一起使用: future 和 promise ?

我应该如何编写这个功能,以便 scala 程序员能够以规范的方式与其交互?例如:

// long running method in the web worker
val f: Future[String] = Registry.ultimateQuestion(42) // async

f onSuccess { case q => println("The ultimate question is: " + q) }

我对 futures 和 Promise 很陌生,但似乎它们通常在某些执行 block 终止时完成。在这种情况下,收到网络 worker 的响应就意味着 future 的完成。有没有办法编写一个自定义 future ,将其完成状态委托(delegate)给外部流程?是否有另一种方法可以将 Web Worker 响应消息链接到 future 的状态?

我可以/应该扩展 Future 特征吗?这在 Scala.js 中可能吗?我应该扩展一个具体的类(class)吗?是否有其他方法可以将这些跨上下文 Web Worker 方法调用封装到现有的异步 Scala 功能中?

感谢您的考虑。

最佳答案

嗯。只是在这里吐槽一下(我还没有使用过 worker ),但在您正在工作的单线程 JavaScript 世界中,将请求与 Future 关联起来似乎相当容易。

这是一个假设的设计。假设对工作人员的每个请求/响应都自动包装在一个信封中;信封包含一个 RequestId。所以发送端看起来像这样(这是伪代码,但是真实的):

def sendRequest[R](msg:Message):Future[R] = {
  val promise = Promise[R]
  val id = nextRequestId()
  val envelope = Envelope(id, msg)
  register(id, promise)
  sendToWorker(envelope)
  promise.future
}

工作进程处理消息,将结果包装在另一个信封中,然后结果在主线程中处理回,如下所示:

def handleResult(resultEnv:Envelope):Unit = {
  val promise = findRegistered(resultEnv.id)
  val result = resultEnv.msg
  promise.success(result)
}

这需要一些填充,并且需要考虑像 R 这样的类型应该是什么,但这种大纲可能会很好地工作。如果这是 JVM,你就必须担心各种竞争条件,但在单线程 JS 世界中,它可能就像使用自动递增整数作为请求 ID 并存储 Promise 一样简单......

关于multithreading - 如何在 future 中包装 Web Worker 响应消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44348491/

相关文章:

scala - 可以在变量名后插入带有字母数字的字符串吗?

c - 尝试使用 pthread 实现竞争条件

java - 在 Android 上创建了一个简单的计时器,没有按预期工作

swift - 在尝试使用主线程时不明确使用 DispatchQueue

scala - Future.onComplete : can't understand the method signature

javascript - 如何在 javascript 中实现类似同步的行为?

asynchronous - 进行地面AsyncTask

c++ - 在 while 循环中将线程置于另一个线程中

templates - Play 2.x 空安全合并(避免模板中的 NPE)

json - 使用 play.api.libs.json 将对象序列化为 json