我怎样才能 运行 Kotlin 在@ReactMethod (ReactNative) 上暂停乐趣
How can I run Kotlin suspend fun on @ReactMethod (ReactNative)
我需要在 Kotlin 本机端 上实现自定义 gRPC。
@ReactMethod
不能是 suspend func
。
我怎样才能运行呢?
@ReactMethod
fun connect(ipAddress: String, port: Int) {
try {
channel = ManagedChannelBuilder.forAddress(ipAddress, port).usePlaintext().build()
var guidKey = Metadata.Key.of("GUID", Metadata.ASCII_STRING_MARSHALLER)
metadata.put(guidKey, GUID)
val stub = DBServiceGrpcKt.DBServiceCoroutineStub(channel!!)
var request = GrpcDBService.SignInRequest.newBuilder()
.setUserName("user")
.setPassword("11111")
.build()
try {
//******* this part *****
suspend fun coroutine() {
var response = stub.trySignIn(request,metadata)
}
} catch (e: Exception) {
Log.d("grpcConnect", e.localizedMessage)
}
} catch (e: Error) {
Log.d("grpcConnect ", e.localizedMessage)
}
finally {
channel?.shutdown()
}
}
您需要创建一个协同程序,例如,定义一个范围(在您的 class 中的某处)并将其与启动一起使用:
myPluginScope.launch {
val response = stub.trySignIn(request,metadata)
// Return, the result
}
创建作用域很容易,棘手的部分是找到取消它的位置。查看有关 React 本机模块的文档,找到在您的范围内调用 cancel
的好地方:
val myPluginScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
现在,决定 connect
函数是否应该作为异步函数运行很重要。例如,如果登录操作需要时间或使用网络,connect
应该可能 return 通过 Promise
或 Callback
结果,所以 Javascript侧面未被阻挡:
@ReactMethod
fun connect(ipAddress: String, port: Int, promise: Promise) {
myPluginScope.launch {
try {
// Make the sign in happen in a separate thread:
val response = withContext(context = Dispatchers.IO) {
stub.trySignIn(request, metadata)
}
// Resolve the promise in the calling thread (The UI thread)
promise.resolve(response.hypotheticalCode)
} catch (e: Exception) {
promise.reject("Sign in error!", e)
}
}
}
见:
https://reactnative.dev/docs/native-modules-android#promises
https://kotlinlang.org/docs/async-programming.html#coroutines
我需要在 Kotlin 本机端 上实现自定义 gRPC。
@ReactMethod
不能是 suspend func
。
我怎样才能运行呢?
@ReactMethod
fun connect(ipAddress: String, port: Int) {
try {
channel = ManagedChannelBuilder.forAddress(ipAddress, port).usePlaintext().build()
var guidKey = Metadata.Key.of("GUID", Metadata.ASCII_STRING_MARSHALLER)
metadata.put(guidKey, GUID)
val stub = DBServiceGrpcKt.DBServiceCoroutineStub(channel!!)
var request = GrpcDBService.SignInRequest.newBuilder()
.setUserName("user")
.setPassword("11111")
.build()
try {
//******* this part *****
suspend fun coroutine() {
var response = stub.trySignIn(request,metadata)
}
} catch (e: Exception) {
Log.d("grpcConnect", e.localizedMessage)
}
} catch (e: Error) {
Log.d("grpcConnect ", e.localizedMessage)
}
finally {
channel?.shutdown()
}
}
您需要创建一个协同程序,例如,定义一个范围(在您的 class 中的某处)并将其与启动一起使用:
myPluginScope.launch {
val response = stub.trySignIn(request,metadata)
// Return, the result
}
创建作用域很容易,棘手的部分是找到取消它的位置。查看有关 React 本机模块的文档,找到在您的范围内调用 cancel
的好地方:
val myPluginScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
现在,决定 connect
函数是否应该作为异步函数运行很重要。例如,如果登录操作需要时间或使用网络,connect
应该可能 return 通过 Promise
或 Callback
结果,所以 Javascript侧面未被阻挡:
@ReactMethod
fun connect(ipAddress: String, port: Int, promise: Promise) {
myPluginScope.launch {
try {
// Make the sign in happen in a separate thread:
val response = withContext(context = Dispatchers.IO) {
stub.trySignIn(request, metadata)
}
// Resolve the promise in the calling thread (The UI thread)
promise.resolve(response.hypotheticalCode)
} catch (e: Exception) {
promise.reject("Sign in error!", e)
}
}
}
见:
https://reactnative.dev/docs/native-modules-android#promises
https://kotlinlang.org/docs/async-programming.html#coroutines