我尝试在Firestore中使用这两种方法,我的函数是这个
fun setDataIntoFirestore(data: HashMap<String,Any>): Either<Failure,Boolean>{
db.collection("test")
.add(data)
.addOnSuccessListener {
//Here I need Either.Right(true);
}
.addOnFailureListener {
Log.d("FirestoreData", "Failure: " + it.message)
//Here I want to add Either.Left(it)
}
}我之所以尝试这样做,是因为我想在数据添加到数据库时通知我的视图,但是当我标记要返回的函数时,我需要返回该类型,并且我不能在Task中返回任何建议我的内容。
关于如何实现这一点有什么想法吗?
我从我的用例中调用这个方法,如下所示
class SendProductUseCase: UseCase<Boolean, HashMap<String, Any>>() {
private val repo = SendProductRepo()
override suspend fun run(params: HashMap<String, Any>): Either<Failure, Boolean> {
return repo.setDataIntoFirestore(params)
}
}而UseCase是每个UseCase的通用And
abstract class UseCase<out Type, in Params> where Type : Any {
abstract suspend fun run(params: Params): Either<Failure, Type>
operator fun invoke(params: Params, onResult: (Either<Failure, Type>) -> Unit = {}) {
val job = GlobalScope.async(Dispatchers.Default) { run(params) }
GlobalScope.launch(Dispatchers.Main) { onResult(job.await()) }
}
class None
}谢谢
发布于 2019-09-11 20:45:10
你可以使用interface让它返回你想要的东西,或者我更喜欢发送更高阶的函数,并在你想要的地方使用它。
您的代码将如下所示
fun setDataIntoFirestore(data: HashMap<String,Any> , retValue : (Either<Failure,Boolean>) -> (Unit)){
db.collection("test")
.add(data)
.addOnSuccessListener {
retValue.invoke(Either.Right(true))
}
.addOnFailureListener {
Log.d("FirestoreData", "Failure: " + it.message)
//Here I want to add Either.Left(it)
}
}你可能会发现复杂的错误,但这是为了证明我的想法
发布于 2019-09-11 21:37:35
onScuccess()和onFailure()方法都是异步的,这意味着只有当数据提交给Firebase服务器或被Firebase服务器拒绝时,它们才会触发。因此,这将需要一些时间,因此一个或另一个方法将被触发,并且不能保证需要多长时间。根据您的连接速度和状态,可能需要几百毫秒甚至几秒的时间。因此,您不可能将Either<Failure,Boolean>类型的对象作为方法的结果返回。为了解决这个问题,我建议你看看我在这个中的最后一部分,我已经解释了如何使用自定义回调来完成这项工作。
附言:有一段出色的视频,道格·史蒂文森在实践中解释了如何使用LiveData实现这一目标
https://stackoverflow.com/questions/57889417
复制相似问题