2014-11-24 72 views
20

我试图在Scala.js中使用Promises and Futures。承诺有效,一旦涉及期货,我会收到警告和错误。Scala.js期货

尝试:

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来处理浏览器事件?

回答

27

由于Scala.js 0.6.0,斯卡拉的标准globalExecutionContext在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,但这些并不提供Future所要求的共享内存模型。

老答案适用于Scala.js < 0.6.0

有2个现有及scala.scalajs.concurrent.JSExecutionContext工作ExecutionContext S,在内部对象Implicits隐含的版本。只需导入一个对你有意义的文件(可能是queue,另一个没有实际异步)。

import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue 

// now you get to play with Futures 
+0

短研究后,'queue'被实现或者使用[承诺](https://www.promisejs.org/)或使用[超时](http://www.w3schools.com/ jsref/met_win_settimeout.asp)适用于不支持承诺的旧浏览器。 – Suma 2017-01-06 12:12:05

+0

注意:'queue'在代码稍后被执行的意义上是异步的(在解析的Promise或setTimeout上使用),但代码并不是并行运行。对于真正的“并行”(并发)任务,您需要Web Workers,例如使用来自github.com/nolanlawson/promise-worker的库。还是我在这里错了? – Suma 2017-01-06 13:12:05

+0

@Suma你是对的。 JavaScript中没有共享内存并行性,所以'Promise'和'Future'不能并行执行。如果需要并行性,你需要使用Web Workers,但是你失去了共享内存,这从根本上改变了事情本身的工作方式。 – sjrd 2017-01-06 14:17:23