【问题标题】:From Completable to Observable从可完成到可观察
【发布时间】:2026-02-02 23:55:02
【问题描述】:

我会尽量说得更清楚。

我想循环一个列表中的元素,对于 MAIN_LIST 中的每个元素,开始一个细化。详细说明包含在另一个列表 SECOND_LIST 中,该列表必须循环。当 SECOND_LIST 的每个项目的所有细节都完成后,开始对 MAIN_LIST 中的下一个元素执行相同的操作。

完成详细说明 MAIN_LIST 中的所有元素时返回完成。

这是我尝试实现的,但我认为有更好的方法。

感谢您的帮助!

循环 MAIN_LIST 的方法

    public Completable checkGroupExpiration(List<CheckVersion.ServiceStatus> serviceStatusList) {
    return Completable.create(emitter -> {
        Observable.fromIterable(serviceStatusList)
                .concatMapCompletable(serviceStatus -> {
                    return checkGroupExpiration(serviceStatus.service, serviceStatus.lastUpdate);
                }).subscribe(new CompletableObserver() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onComplete() {
                if (!emitter.isDisposed())
                    emitter.onComplete();
            }

            @Override
            public void onError(Throwable e) {
                if (!emitter.isDisposed())
                    emitter.onComplete();
            }
        });
    });
}

循环 SECOND_LIST 的方法

    protected Completable checkGroupExpiration(String group, long ttl) {
    return Completable.create(emitter -> {
        readFile(MASTER_NOTE)
                .map(s -> {
                    return new Gson().fromJson(s, MasterNote.class);
                }).flatMapObservable(masterNote -> {
            return Observable.fromIterable(masterNote.savedFiles.entrySet());
        }).filter(stringCacheInfoEntry -> {
            return stringCacheInfoEntry.getValue().group.equals(group) && stringCacheInfoEntry.getValue().ttl < ttl;
        }).concatMapCompletable(stringCacheInfoEntry -> {
            return getFile(stringCacheInfoEntry.getKey(), false)
                    .doOnSuccess(file -> {
                        String fileName = file.getName();
                        file.delete();
                        Log.d(TAG, "File deleted => " + fileName + " from group => " + group);
                    }).ignoreElement();
        }).subscribe(new CompletableObserver() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onComplete() {
                if (!emitter.isDisposed())
                    emitter.onComplete();
            }

            @Override
            public void onError(Throwable e) {
                if (!emitter.isDisposed())
                    emitter.onComplete();
            }
        });
    });
}

【问题讨论】:

    标签: android asynchronous rx-java2


    【解决方案1】:

    是的,有。不要订阅create 中的内部流,而是直接使用流:

    public Completable checkGroupExpiration(
            List<CheckVersion.ServiceStatus> serviceStatusList) {
        retrn Observable.fromIterable(serviceStatusList)
                .concatMapCompletable(serviceStatus -> 
                    checkGroupExpiration(serviceStatus.service, serviceStatus.lastUpdate)
                )
                .ignoreElements();
    }
    
    protected Completable checkGroupExpiration(String group, long ttl) {
        return 
             readFile(MASTER_NOTE)
             .map(s ->
                    new Gson().fromJson(s, MasterNote.class)
             )
             .flatMapObservable(masterNote ->
                  Observable.fromIterable(masterNote.savedFiles.entrySet())
             )
             .filter(stringCacheInfoEntry ->
                  stringCacheInfoEntry.getValue().group.equals(group) 
                  && stringCacheInfoEntry.getValue().ttl < ttl
             )
             .concatMapCompletable(stringCacheInfoEntry -> 
                  getFile(stringCacheInfoEntry.getKey(), false)
                  .doOnSuccess(file -> {
                        String fileName = file.getName();
                        file.delete();
                        Log.d(TAG, "File deleted => " + fileName + " from group => " + group);
                  })
                  .ignoreElement()
            );
    }
    

    【讨论】:

    • 如果我想循环 main_list 异步启动 second_list 的所有循环并等待所有循环完成?