当我在Scala.js中使用期货时,至少在测试中,它们永远不会执行,我不能等待它们。
给出这个简单的测试:
package example
import utest._
import utest.framework.{Test, TestSuite}
import utest.util.Tree
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
import scala.language.postfixOps
import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue
object SomeFutureTest extends TestSuite {
override def tests: Tree[Test] =
TestSuite {
'runs_future {
val eventualString: Future[String] = Future[String] {
"foo"
}
Await.result(eventualString, 5 seconds)
}
}
}当我在sbt控制台上运行test时,我得到:
JavaException: org.scalajs.jsenv.rhino.ScalaJSCoreLib$ClassNotFoundException:
Rhino was unable to load Scala.js class: ju_concurrent_locks_AbstractQueuedSynchronizer当我像这样做一个讨厌的hack而不是Await时:
while(!future.isCompleted) {}它永远在运行。
Await在scala.js中不起作用吗?在测试中使用Futures和Await他们的结果是不可能的吗?
编辑:它使用scala.scalajs.concurrent.JSExecutionContext.Implicits.runNow而不是queue,但它以同步的方式调用期货。
发布于 2015-04-30 02:33:38
实际上,Await不能在Scala.js中工作。它不能,因为它是一个阻塞API,并且在JS环境中没有阻塞这回事。
出于这个原因,测试框架以一种特殊的方式支持Future,允许测试本身返回其执行的Future。然后,测试框架负责维护异步,直到最终显示单元测试的结果。
作为documented in its Readme,uTest支持这一点。在您的情况下,这将提供:
TestSuite {
'runs_future {
val eventualString: Future[String] = Future[String] {
"foo"
}
for (theString <- eventualString) yield {
assert(theString == "foo")
// and/or:
theString
}
}
}如果您更习惯使用map表示法,以下是等效的表示法:
TestSuite {
'runs_future {
val eventualString: Future[String] = Future[String] {
"foo"
}
eventualString map { theString =>
assert(theString == "foo")
// and/or:
theString
}
}
}https://stackoverflow.com/questions/29951327
复制相似问题