持续错误:未解析的引用:使用 kotlinx-coroutines-core-js:1.7.3 时出现 runBlocking

Persistent error: Unresolved reference: runBlocking when using kotlinx-coroutines-core-js:1.7.3

提问人:Mikael Vejdemo-Johansson 提问时间:11/12/2023 最后编辑:Mikael Vejdemo-Johansson 更新时间:11/13/2023 访问量:22

问:

我正在尝试使用协程和 Arrow 库函数来并行化我正在研究的科学计算库中的一些代码。在我读到的任何地方,该函数都被使用并推荐用于从串行阻塞代码上下文到协程代码上下文。parMapNotNullkotlinx.coroutines.runBlocking

但是,我不断收到编译错误

e: file:///Users/mik/IdeaProjects/tda4j/src/commonMain/kotlin/org/appliedtopology/tda4j/ParallelSymmetricSimplexIndexVietorisRips.kt:16:9 Unresolved reference: runBlocking

我能够专门针对 JVM 目标解决该问题,但即使导入了 ,我也会获得任何 JS 编译代码的未解决参考。kotlinx-coroutines-core-js

我的包括build.gradle.kts

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
                implementation("io.arrow-kt:arrow-core:1.2.1")
                implementation("io.arrow-kt:arrow-fx-coroutines:1.2.1")
                implementation("space.kscience:kmath-core:0.3.1")
                implementation("space.kscience:kmath-tensors:0.3.1")
            }
        }
        val commonTest by getting {
            dependencies {
                implementation("io.kotest:kotest-framework-engine:5.7.2")
                implementation("io.kotest:kotest-assertions-core:5.7.2")
                implementation("io.kotest:kotest-property:5.7.2")
            }
        }
        val jvmMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3")
            }
        }
        val jvmTest by getting {
            dependencies {
                implementation("io.kotest:kotest-runner-junit5:5.7.2")
            }
        }
        val jsMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.7.3")
            }
        }

编辑添加, 2023-11-12:

继 Marko Topolnik 的评论之后,我的代码中有一个结构,看起来有点像这样:

class Foo {
  val cache : Array<Sequence<stuff>> = Array(somesize) { emptySequence<stuff> }
  val scope = CoroutineScope(Dispatchers.Default)

  fun doStuff(d : Int): Sequence<stuff> {
    runBlocking(Dispatchers.Default) {
      if(cache[d].none()) {
        val stuffJob = async {
          somecollection.parMapNotNull { doSomethingExpensive }
            .map { convertresult }
            .sorted()
            .asSequence()
        }
        cache[d] = stuffJob.await()
      }
    }
    return cache[d]
  }
}

只要我根本不关心JS,这似乎确实有效。但是,我最初选择 Kotlin 的部分原因是多平台支持。如果我用 代替 来写这个,那么什么都不会返回。scope.launchrunBlocking

在库的其他地方,我用来允许我处理互斥锁以写入缓存数据结构,这些内容在这里被调用。runBlockingdoSomethingExpensive

无论我转向哪里,看起来为了使用,我需要已经在协程中,而用于转换到或退出协程上下文的东西就是使用 - 除了代码不再是多平台的。launchrunBlocking

我试着做这样的事情:

class Foo {
  val cache : Array<Sequence<stuff>> = Array(somesize) { emptySequence<stuff> }
  val scope = CoroutineScope(Dispatchers.Default)

  fun doStuff(d : Int): Sequence<stuff> {
    scope.launch(Dispatchers.Default) {
      if(cache[d].none()) {
        val stuffJob = async {
          somecollection.parMapNotNull { doSomethingExpensive }
            .map { convertresult }
            .sorted()
            .asSequence()
        }
        cache[d] = stuffJob.await()
      }
    }.join()
    return cache[d]
  }
}

但是,如果我还没有在协程上下文中,则不允许使用,因此我不能使用它来等待我的并行作业完成,然后再编译和返回结果。join

我还尝试过做这样的事情:

class Foo {
  val cache : Array<Sequence<stuff>> = Array(somesize) { emptySequence<stuff> }
  val scope = CoroutineScope(Dispatchers.Default)

  fun doStuff(d : Int): Sequence<stuff> {
    scope.launch(Dispatchers.Default) {
      if(cache[d].none()) {
        val stuffJob = async {
          somecollection.parMapNotNull { doSomethingExpensive }
            .map { convertresult }
            .sorted()
            .asSequence()
        }
        cache[d] = stuffJob.await()
      }
    }
    while(cache[d].none()) { }
    return cache[d]
  }
}

但是在JVM(我已知的工作平台)上运行它来测试东西,它似乎进入了一个无限循环,在测试代码上花费的时间比以前多得多。

kotlin kotlin-multiplatform kotlin-js arrow-kt

评论

0赞 Marko Topolnik 11/12/2023
runBlocking对于 JS 来说没有意义,因为 JS 不允许任何代码阻塞线程。请尝试改用。launch

答: 暂无答案