在应用程序中,它将从多个端点获取数据以为调用方构造一个组合流,因此一个端点将有多个FetchRemoteDataCommand
。喜欢
val fetchers = getFetchers (...) //returns ArrayList<FetchRemoteDataCommand> with different endpoints
for (f in fetchers) {
f.doPost()
}
当前,它不使用协程,而是根据回调onDataFetchComplete
将结果传递回调用方。调用者必须管理每个提取程序的状态,才能最终将每个提取程序的所有结果组合在一起。
认为协程可能会帮助您进行管理。
如何使用等待所有提取程序完成其改造调用,然后根据所有提取程序的结果构建聚合流的协程,来做到这一点?
是否可以像这样完成
: runBlocking {
for (f in fetchers) {
launch { f.doPost() }
}
}
// now all fetcher has finished
var resultStream = ArrayList<T>()
for (f in fetchers) {
resultStream.add(f.dgetResult())
}
还是其他更好的方法?
FetchRemoteDataCommand
类
class FetchRemoteDataCommand<T>(val baseUrl: String,
val path: String,
var headers: HashMap<String, String>,
var params: HashMap<String, String>,
val body: okhttp3.RequestBody? = null,
callback: ICallback<IData<T>>,
var httpClient: OkHttpClient,
POJOClassType: Class<T>) {
private var fetchCompleteCallback: ICallback<IGenericData<T>> = callback
val mPOJOClazz: Class<T> = POJOClassType
var resultData: T? = null
fun getResult(): T? {
return resultData
}
suspend fun doPost() {
val service = createRetrofitService(IRemoteDataRequest::class.java, baseUrl, httpClient)
service.postForData(path, headers, params, body!!).enqueue(object : Callback<ResponseBody> {
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
try {
val jsonString: String = response.body()?.string() ?: ""
resultData = try {
Gson().fromJson<T>(jsonString, mPOJOClazz)
} catch (e: Exception) {
null
}
val headerList = response.headers()
val errorBodyString = response.errorBody()?.string()
val success = response.isSuccessful
val contentType = response.body()?.contentType()
val code = response.code() ?: -1
var message = response.message() ?: ""
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()).execute {
fetchCompleteCallback.onDataFetchComplete(resultData, success, code, message, errorBodyString, contentType, headerList)
}
} finally {
response.body()?.close()
}
}
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()).execute {
fetchCompleteCallback.onDataFetchComplete(null, false, -1, t.message ?: "", null, null, null)
}
}
})
}
fun <T> createRetrofitService(clazz: Class<T>, endPoint: String, httpClient: OkHttpClient): T {
val restAdapter = Retrofit.Builder()
.baseUrl(endPoint)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.build()
return restAdapter.create(clazz)
}
}
interface IRemoteDataRequest {
@POST
fun postForData(@Url url: String,
@HeaderMap headers: Map<String, String>,
@QueryMap params: Map<String, String>?, @Body body: RequestBody): Call<ResponseBody>
}