我的应用程序中有几个资源我需要在首次启动时加载并转储到我的数据库中。我想平行地做这件事。
所以我在阅读文件时创建了一个可观察的包装器。
@Override
public Observable<List<T>> loadDataFromFile() {
return Observable.create(new Observable.OnSubscribe<List<T>>() {
@Override
public void call(Subscriber<? super List<T>> subscriber) {
LOG.info("Starting load from file for %s ON THREAD %d" + type, Thread.currentThread().getId());
InputStream inputStream = null;
try {
Gson gson = JsonConverter.getExplicitGson();
inputStream = resourceWrapper.openRawResource(resourceId);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
List<T> tList = gson.fromJson(inputStreamReader, type);
subscriber.onNext(tList);
subscriber.onCompleted();
LOG.info("Completed load from file for " + type);
} catch (Exception e) {
LOG.error("An error occurred loading the file");
subscriber.onError(e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
}
});
}
然而,它不是异步的,我看到有两种方法使这种异步:
1)在可观察的Spawn中进行异步处理新线程或使用基于回调的文件读取api。
2)使用调度程序在I / O线程上进行工作,
再次对于DB我必须创建自己的observable来包装数据库Api,并且有一个带回调的同步和异步版本。
那么创建i / o工作的observable的正确方法是什么?
其次我如何在链中使用这些observable来并行读取这些文件,然后为每个存储在DB中的内容。我希望在完成所有参考数据的整个过程后收到onCompleted事件。
答案 0 :(得分:2)
关于RX的一个好处是你可以控制你的&#34;工作&#34;已经完成了。你可以使用
subscribeOn(Schedulers.io())
如果要并行加载资源,我建议使用merge(或mergeDelayError)运算符。
假设你有一个功能
Observable<List<T>> loadDataFromresource(int resID)
要加载一个资源,您可以先为每个资源创建一个observable列表
for (int i=0 ; i<10; i++) {
obsList.add(loadDataFromresource(i+1).subscribeOn(Schedulers.io()));
}
将调度程序与每个可观察对象相关联。使用
合并可观察量Observable<List<T>> mergedObs = Observable.merge(obsList);
然后,订阅生成的observable应该并行加载资源。如果您希望将错误延迟到合并的observable结束,请使用
Observable<List<T>> mergedObs = Observable.mergeDelayError(obsList);
答案 1 :(得分:1)
我不是Java开发人员,但在C#中,这基本上就是这种代码的结构:
public IObservable<string> LoadDataFromFile()
{
return
Observable.Using(
() => new FileStream("path", FileMode.Open),
fs =>
Observable.Using(
() => new StreamReader(fs),
sr => Observable.Start(() => sr.ReadLine())));
}
希望你能从中适应。