【问题标题】:"Cannot find an implicit ExecutionContext" error in scala.js example app.scala.js 示例应用程序中的“找不到隐式 ExecutionContext”错误。
【发布时间】:2015-12-02 22:41:31
【问题描述】:

这是动手 Scala.js 电子书中的一个示例:

package webpage

import org.scalajs.dom.ext.Ajax

import scala.scalajs.js
import scala.scalajs.js.annotation.JSExport
import scalatags.JsDom.all._
import org.scalajs.dom
import dom.html

@JSExport
object HelloWorld1 extends {
  @JSExport
  def main(target: html.Div) = {

    lazy val box = input(
      `type`:="text",
      placeholder:="Type here!"
    ).render

    lazy val output = div(
      height:="400px",
      overflowY:="scroll"
    ).render

    box.onkeyup = (e: dom.Event) => {
      output.innerHTML = "Loading..."
      fetchWeather(box.value)
    }

    target.appendChild(
      div(
        h1("Weather Search"),
        p(
          "Enter the name of a city to pull the ",
          "latest weather data from api.openweathermap.com!"
        ),
        p(box),
        hr, output, hr
      ).render
    )

    def fetchWeather(query: String) = {
      val searchUrl =
        "http://api.openweathermap.org/data/" +
          "2.5/find?type=like&mode=json&q=" +
          query

      for{
        xhr <- Ajax.get(searchUrl)
        if query == box.value
      } js.JSON.parse(xhr.responseText).list match{
        case jsonlist: js.Array[js.Dynamic] =>
          output.innerHTML = ""
          showResults(jsonlist, query)
        case _ =>
          output.innerHTML = "No Results"
      }
    }
    def showResults(jsonlist: js.Array[js.Dynamic], query: String) = {
      for (json <- jsonlist) {
        val name = json.name.toString
        val country = json.sys.country.toString
        val weather = json.weather.pop().main.toString

        def celsius(kelvins: js.Dynamic) = {
          kelvins.asInstanceOf[Double] - 273.15
        }.toInt

        val min = celsius(json.main.temp_min)
        val max = celsius(json.main.temp_max)
        val humid = json.main.humidity.toString
        val (first, last) = name.splitAt(query.length)
        output.appendChild(
          div(
            b(span(first, backgroundColor:="yellow"), last, ", ", country),
            ul(
              li(b("Weather "), weather),
              li(b("Temp "), min, " - ", max),
              li(b("Humidity "), humid, "%")
            )
          ).render
        )
      }
    }
  }
}

编译时出错:

[info] Compiling 1 Scala source to /Users/kaiyin/personal_config_bin_files/workspace/workbench-example-app/target/scala-2.11/classes...
[error] /Users/kaiyin/personal_config_bin_files/workspace/workbench-example-app/src/main/scala/HelloWorld1.scala:51: Cannot find an implicit ExecutionContext. You might pass
[error] an (implicit ec: ExecutionContext) parameter to your method
[error] or import scala.concurrent.ExecutionContext.Implicits.global.
[error]         if query == box.value
[error]                  ^
[warn] /Users/kaiyin/personal_config_bin_files/workspace/workbench-example-app/src/main/scala/HelloWorld1.scala:53: non-variable type argument scala.scalajs.js.Dynamic in type pattern scala.scalajs.js.Array[scala.scalajs.js.Dynamic] is unchecked since it is eliminated by erasure
[warn]         case jsonlist: js.Array[js.Dynamic] =>
[warn]                           ^
[warn] one warning found
[error] one error found
[info] workbench: Checking example-fastopt.js
[info] workbench: Checking webpage-fastopt.js
[error] (compile:compile) Compilation failed
[error] Total time: 0 s, completed 7 sept. 2015 12:51:38
78. Waiting for source changes... (press enter to interrupt)

这里出了什么问题?

【问题讨论】:

    标签: scala scala.js implicits


    【解决方案1】:

    正如错误提示,添加以下导入:

    import scala.concurrent._
    import ExecutionContext.Implicits.global
    

    【讨论】:

    • 我相信答案的前半部分是正确的(IIRC,scala.concurrent.ExecutionContext.Implicits.global 别名为 scala.scalajs.concurrent.JSExecutionContext.queue,这是你想要的),但后半部分不是。请记住,这是一个 Scala.js 问题——没有线程池或线程之类的东西。它是一个单线程执行引擎,因此它是一个更简单的环境......
    • @JustinduCoeur,我不熟悉 Scala.js。无论如何,这没有意义。通过导入隐式提供的默认线程执行环境是一个 forkjoinpool,其启动的线程数等于机器上的处理器数。因此,如果这不是所需的语义,那么第一部分也是错误的。随意将答案完全编辑为您认为正确的答案。
    • Scala.js 是 Scala 运行时的重新实现,可以在 JavaScript 上而不是 JVM 上运行。唯一可用的线程执行环境是一个特殊的单线程环境,因为 JavaScript 从根本上说是单线程的——诸如 fork/join 池之类的东西是 non-sequiteurs,因为它们是 JVM 特有的。 在语法上,您仍然需要添加 ExecutionContext 的导入,以使 Scala 编译器满意,但它只有一个合法的定义...
    • @JustinDuCoeur 最后一点实际上不是 100% 正确的。在提供 JavaScript Promise 的较新的 JS 环境中,执行上下文可以选择使用 Promise 事件循环(紧密循环)或 setTimeout 事件循环(UI 事件循环)。
    • 在问题的第二部分得到解决之前投反对票。
    【解决方案2】:

    我使用“import net.kaliber.mailer._”使用 Scala 发送电子邮件。 并得到“没有为参数 ec 找到隐含:”错误。 导入以下 2 个库后,该问题得到解决。

    import scala.concurrent._
    
    import ExecutionContext.Implicits.global
    

    【讨论】:

    • 你没有导入两个库,只是一个对象。你的两行相当于import scala.concurrent.ExecutionContext.Implicits.global
    猜你喜欢
    • 2013-02-04
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 2016-01-23
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多