Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 结合使用suspend函数和coroutineScope构建dsl的惯用方法_Kotlin_Coroutine_Kotlin Coroutines - Fatal编程技术网

Kotlin 结合使用suspend函数和coroutineScope构建dsl的惯用方法

Kotlin 结合使用suspend函数和coroutineScope构建dsl的惯用方法,kotlin,coroutine,kotlin-coroutines,Kotlin,Coroutine,Kotlin Coroutines,我们正在为我们的用户构建一个dsl来编写域脚本,我们希望通过这样的脚本满足以下期望: 异步和非阻塞 默认行为应该是连续的 应该能够在需要时并行运行任务 我们的目标是对脚本作者隐藏所有的机器 脚本编写器不应看到诸如coroutinescope,async,launch之类的关键字 我们已经在suspend函数上提供了很多包装器,作为我们的dsl for ex的一部分 //dsl fun-handleCommand(f:suspend(Command)->CommandResult) //来自脚

我们正在为我们的用户构建一个dsl来编写域脚本,我们希望通过这样的脚本满足以下期望:

  • 异步和非阻塞
  • 默认行为应该是连续的
  • 应该能够在需要时并行运行任务
  • 我们的目标是对脚本作者隐藏所有的机器

    • 脚本编写器不应看到诸如
      coroutinescope
      async
      launch
      之类的关键字
    • 我们已经在suspend函数上提供了很多包装器,作为我们的dsl for ex的一部分
    //dsl
    fun-handleCommand(f:suspend(Command)->CommandResult)
    //来自脚本的用法
    handleCommand{cmd->
    val event=getEvent()//挂起函数
    // .....
    }
    
    在这里,脚本编写器不需要担心
    异步
    非阻塞
    ,所有内容都是从它们中抽象出来的

    • 现在我们需要一个实用程序,它在
      并行
      中运行
      任务
      ,为此,我们提供了以下
      par
      函数
    //dsl
    暂停乐趣par(块:()->T):延迟=协同作用域{
    异步{block()}
    }
    //用法
    handleCommand{cmd->
    PAR {//TASK1}
    PAR {//TASK2}
    //调用其他挂起函数
    }
    
    • 由于
      par
      正在挂起函数并获取一块代码并在新的协同程序中运行,我们可以在
      parallel

    • 由于
      par
      是从
      handleCommand
      (挂起函数)调用的,所以所有功能都可以正常工作,用户不需要处理
      协同程序和家庭

    所以问题是,函数
    par
    ->
    suspend-fun-par(block:()->T):Deferred
    的签名似乎不是惯用的,也不符合使用
    suspend
    CoroutineScope
    扩展的一般准则。
    根据上面的用例/限制,我做得对吗?还是有更好的方法来实现同样的效果?

    似乎您想要定义一个关键字来异步运行作业。。。您是否考虑过
    async
    par
    使用
    async
    在内部生成新的
    coroutine
    ,但它不需要从
    coroutineScope
    调用,因为它也是从
    suspend
    函数
    par{/…}调用的
    这会立即开始在后台执行您的
    par
    调用将在内部启动的协同程序完成之前完成。您必须将指定每行代码在其中启动后台任务的块与实际启动任务的函数解耦。但是,事实就是这样:
    coroutineScope
    是前者,
    async
    (或者更适合您的用例,
    launch
    )是后者。另一方面,如果您想摆脱coroutine作用域块,那么您已经选择在没有结构化并发的情况下工作。我不建议这样做。@MarkoTopolnik,是的,正如你在第一次评论中所说,它没有按照我希望的方式工作。上面的
    par
    实现从调用范围挂起。我希望它在后台运行。另外,正如您在秒注释中提到的,
    launch
    async
    在直接使用时确实可以正常工作。因此,让我们假设我的用例是,我想将
    launch
    async
    重命名为
    par
    以保持行为不变,那么我该如何做呢?