2017-12-03 4 views
1

Ich mache eine Listview, welche Call-Funktion, wenn Sie klicken.Asynchrone anonyme Funktion in Kotlin? (Lambda-Ausdrücke)

und I want to get function is async or sync.

zu blockieren, wenn es async ist.

und sogar ich möchte wissen how attach async mark to kotlin lambda expression.

class FunctionCaller_Content(text: List<String>, 
          val function: List< /*suspend? @async? */ 
                ( () -> Unit )? 
               >? = null) 
               /* I want both of async, sync function. */ 
{ 

    fun isAsnyc(order: Int): Boolean 
     = // how to get this lambda expression{function?.get(order)} is async? 

    fun call(callerActivity: Activity, order: Int) { 
     val fun = function?.get(order) 
     fun() 
     if(isAsync(fun)) 
      /* block click for async func */ 
    } 

} 

und Verwendung.

FunctionCaller_Content(listOf("Click to Toast1", "Click to Nothing"), 
         listOf(
         { 
          Toast.makeText(this, "clicked", Toast.LENGTH_SHORT) 
         }, 
         { 
          /*if async lambda expression, how can i do?*/ 
         }) 

Antwort

2

Sie können List<suspend() -> Unit> haben, aber Sie können nicht beide aussetzen und nicht-Suspend-Funktionen in der gleichen Liste mit Ausnahme von List<Any> verwenden. Ich würde vorschlagen, stattdessen zwei separate Listen zu verwenden. Eine weitere Lösung ist „algebraischer Datentyp“ zu verwenden:

sealed class SyncOrAsync // can add methods here 
class Sync(val f:() -> Unit) : SyncOrAsync 
class Async(val f: suspend() -> Unit) : SyncOrAsync 

class FunctionCaller_Content(text: List<String>, 
          val function: List<SyncOrAsync>? = null) 
{ 

    fun call(callerActivity: Activity, order: Int) { 
     val fun = function?.get(order) 
     if(fun is Async) 
      /* block click for async func */ 
    } 

} 

FunctionCaller_Content( 
    listOf("Click to Toast1", "Click to Nothing"), 
    listOf(Sync { 
       Toast.makeText(this, "clicked", Toast.LENGTH_SHORT) 
      }, 
      Async { 
       // your async code 
      }) 

Aber wenn Sie gerade sowieso zu blockieren, würde ich nur verwenden List<() -> Unit> und

listOf({ 
      Toast.makeText(this, "clicked", Toast.LENGTH_SHORT) 
     }, 
     { 
      runBlocking { 
       // your async code 
      } 
     }) 
+0

Danke. du hilfst mir sehr. aber es ist auf UI-Thread. also muss ich versuchen nur zu klicken. und wie bekomme ich '' 'isAsync()' '' '' 'wenn ich List ' ''? ... ??? unmöglich?? Ich versuche '' 'if (func is (suspend() -> Unit)' '', es funktioniert nicht .... –

+0

und dieser Code funktioniert nicht.T_T ... weil run {} inline ist also gibt es nicht '' '() -> Unit''' zurück. –

+0

Siehe die Änderung für eine andere Alternative –