结合使用suspend函数和coroutineScope来构建dsl的惯用方式

时间:2019-08-31 09:24:23

标签: kotlin coroutine kotlin-coroutines

我们正在为用户编写dsl来编写域脚本,我们希望满足以下对此类脚本的期望:

  1. 异步且非阻塞
  2. 默认行为应该是顺序的
  3. 应该能够在需要时并行运行任务

我们的目标是对脚本编写者隐藏所有机制。

  • 脚本编写者不应看到coroutinescopeasynclaunch之类的关键字。
  • 我们为ex的dsl提供了一堆包装,用于暂停功能。
      // dsl
      fun handleCommand(f: suspend (Command) -> CommandResult)

      // usage from script
      handleCommand { cmd ->
        val event = getEvent() // suspending function
        // .....
      }

脚本编写者无需担心asyncnon-blocking,一切都从它们中提取出来

  • 现在我们想要一个在task中运行parallel的实用程序,为此,我们在par函数之后提供了此功能
     // dsl
      suspend fun <T> par(block: () -> T): Deferred<T> = coroutineScope {
          async { block() }
      }

      // usage 
      handleCommand { cmd ->
        par { //task1  }
        par { //task2  }
        // call other suspending functions
      }

  • 由于par是挂起函数并需要一段代码并在新的协程中运行,因此我们可以在parallel

  • 中运行任意数量的任务>
  • par(暂停功能)中调用handleCommand时,一切正常,用户不需要处理coroutines和家人

问题是,函数par-> suspend fun <T> par(block: () -> T): Deferred<T> 的签名似乎不是惯用的,也不符合使用的一般准则suspendCoroutineScope扩展名。 在上述用例/限制条件下,我可以正确执行此操作吗?还是有更好的方法来实现相同功能?

0 个答案:

没有答案