将回调代码迁移到暂停function

我正在使用协程将我的Android代码从Java重新分解到Kotlin,但是我没有find一种简单的方法来将基于回调的代码重写为挂起的函数。

一个基本的例子是一个警告popup框,返回一个结果,在Javascript中它将是这样的:

let value = prompt("please insert a value") console.log("Value:"+value) 

我会在Kotlin翻译如下:

 class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { //Standard activity initialization super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //Actual code... launch { val value = resolvable(UI) { success, error -> //Build a simple popup prompt with AlertDialog val input = EditText(this@MainActivity) val builder = AlertDialog.Builder(this@MainActivity) .setTitle("please insert a value") .setView(input) .setPositiveButton("Ok",{ dialog, id -> success(input.text.toString())//This lambda returns the value }) val dialog = builder.create() dialog.show() } println("Value:"+ value) } //... } } 

可解析的是我为这个purpuse开发的一个自定义函数,这里是源代码:

 import kotlinx.coroutines.experimental.DefaultDispatcher import kotlinx.coroutines.experimental.cancelAndJoin import kotlinx.coroutines.experimental.launch import java.util.concurrent.Semaphore import kotlin.coroutines.experimental.CoroutineContext suspend fun  resolvable( context: CoroutineContext = DefaultDispatcher, block: suspend (success:(T?)->Unit,error:(Throwable)->Unit) -> Unit ):T?{ var result:T? = null var exception:Throwable? = null val semaphore = Semaphore(0) val job = launch(context){ block({r:T? -> { result=r semaphore.release() }},{e:Throwable -> { exception=e semaphore.release() }}) } semaphore.acquire() job.cancelAndJoin() if(exception!=null) throw exception!! return result } 

我很快使用lambdas和信号量开发了可解析的函数(记住它是一个快速的草稿),但我不知道是否有任何预先存在的函数(我找不到任何函数)或可以优化或有任何缺点/问题。

谢谢。

看起来你正在试图重新suspendCoroutine函数。 我建议用suspendCoroutine调用来取代你的resolvable函数,以获得你正在寻找的functiontypes:

  //Actual code... launch(UI) { val value = suspendCoroutine { cont -> //Build a simple popup prompt with AlertDialog val input = EditText(this@MainActivity) val builder = AlertDialog.Builder(this@MainActivity) .setTitle("please insert a value") .setView(input) .setPositiveButton("Ok",{ dialog, id -> cont.resume(input.text.toString()) //!!! Resume here }) val dialog = builder.create() dialog.show() } println("Value:"+ value) } 

如果在suspendCoroutine块周围执行“提取函数”重构并命名产生的暂停函数prompt ,那么可以用与JS非常相似的样式编写代码。

你也可以考虑使用suspendCancellebleCoroutine而不是简单的suspendCoroutine 。 这样,您可以支持取消启动的协程,并安装一个处理程序以在取消对话时关闭对话框。