【问题标题】:Futures in Scala.jsScala.js 中的期货
【发布时间】:2015-01-22 13:59:45
【问题描述】:

我尝试在 Scala.js 中使用 Promises 和 Futures。 Promise 有效,一旦涉及到 Futures,我就会收到警告和错误。

试试:

val p1 = Promise[Int]
val f1: Future[Int] = p1.future
val p2 = Promise[Int]
val f2: Future[Int] = p2.future

val res1 =  for {
   v1 <- f1
   v2 <- f2
} yield v1 + v2


val res2 = f1.flatMap(x => f2.map(y => x + y))



res1 onSuccess {
  case x: Int => g.console.log(x);

}

res2 onSuccess {
  case x: Int => g.console.log(x);

}

// callback in dom, using ScalaTags
// div(`class` := "btn  btn-default", `type` := "button", onclick := click(1, p1))
def click(i: Int, p: Promise[Int])(x: dom.MouseEvent): Unit = {
  g.console.log(i);
  try {
    p success i
  }
  catch {
    case x: Throwable => println("again")
  }
}

f1 onSuccess {
  case x: Int => 1

}

然后我进入了 sbt fastOptJs:

[warn] Referring to non-existent class jl_Thread$UncaughtExceptionHandler
[warn]   called from s_concurrent_impl_ExecutionContextImpl.init___ju_concurrent_Executor__F1
[warn]   called from s_concurrent_impl_ExecutionContextImpl$.fromExecutor__ju_concurrent_Executor__F1__s_concurrent_impl_ExecutionContextImpl
[warn]   called from s_concurrent_ExecutionContext$Implicits$.global$lzycompute__p1__s_concurrent_ExecutionContextExecutor
[warn]   called from s_concurrent_ExecutionContext$Implicits$.global__s_concurrent_ExecutionContextExecutor
[warn]   called from Lexample_H2$class.Lexample_H2$class__$init$__Lexample_H2__V
[warn] 

然后我进入浏览器:

uncaught exception: java.lang.RuntimeException: System.getProperty() not implemented

缺少/未实现什么?我该如何实施?有解决方法吗? 如何实现一个对使用浏览器处理事件有意义的 ExecutionContext?

【问题讨论】:

    标签: javascript scala promise future scala.js


    【解决方案1】:

    从 Scala.js 0.6.0 开始,Scala 的标准 global ExecutionContext 在 Scala.js 中可用。您可以使用

    import scala.concurrent.ExecutionContext.Implicits.global
    
    // now you get to play with Futures
    

    在 Scala.js 中,它是 scala.scalajs.concurrent.JSExecutionContext.Implicits.queue 的别名。此执行上下文将作业排入标准 JavaScript 事件循环中。

    请注意,任务是异步执行的,但不是并行执行的,因为 JavaScript 本身没有并行的概念。如果需要并行性,则需要使用Web Workers,但它们不提供Futures 所需的共享内存模型。

    适用于 Scala.js 的旧答案

    scala.scalajs.concurrent.JSExecutionContext 中有 2 个现有的和工作的ExecutionContexts,在内部对象Implicits 中有隐式版本。只需导入对您有意义的一个(可能是queue,另一个实际上不是异步的)。

    import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue
    
    // now you get to play with Futures
    

    【讨论】:

    • 经过短暂的研究,queue 是使用 promisestimeouts 对于不支持承诺的旧浏览器实现的。
    • 注意:queue 是异步的,因为代码稍后执行(在解析的 Promise 或 setTimeout 上使用 then),但代码不会并行运行。对于真正的“并行”(并发)任务,您需要 Web Workers,例如使用来自 github.com/nolanlawson/promise-worker 的库。还是我错了?
    • @Suma 你是对的。 JavaScript 中不存在共享内存并行,因此Promises 和Futures 不会并行执行。如果需要并行性,则需要使用 Web Workers,但会丢失共享内存,这从根本上改变了事情本身的工作方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    • 2020-03-31
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多