You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxJava如何获取最先完成的Single的返回值?

当然可以!RxJava完美适配这个需求

你要的这种「同时发起多个请求,取最快返回的结果并忽略其他请求」的场景,RxJava专门提供了amb()(Ambiguous,模糊匹配)操作符来解决,它完全符合你的需求:

核心逻辑说明

amb()操作符会同时订阅所有传入的Single(或Observable),一旦其中任何一个发射了成功/错误事件,就会立刻取消其他所有订阅,只保留第一个完成的结果。正好对应你要的“取最快镜像的User对象,忽略另一个”的诉求。

具体实现步骤

  • 第一步:定义两个对接不同镜像的Single请求(注意要把请求放在IO线程执行,避免阻塞主线程):
// 镜像1的请求Single
Single<User> userFromMirror1 = Single.fromCallable(() -> {
    // 替换成你的实际HTTP GET请求逻辑,比如Retrofit接口调用
    return mirrorApi1.getUserInfo();
}).subscribeOn(Schedulers.io());

// 镜像2的请求Single
Single<User> userFromMirror2 = Single.fromCallable(() -> {
    return mirrorApi2.getUserInfo();
}).subscribeOn(Schedulers.io());
  • 第二步:用amb()组合两个Single,获取最快返回的结果:
// 方式1:使用Single.amb()静态方法传入列表
Single.amb(Arrays.asList(userFromMirror1, userFromMirror2))
    .observeOn(AndroidSchedulers.mainThread()) // Android环境切换到主线程处理结果,非Android可省略
    .subscribe(
        user -> {
            // 拿到最快返回的User对象,执行你的业务逻辑
            updateUserDisplay(user);
        },
        throwable -> {
            // 两个镜像请求都失败时的错误处理逻辑
            showErrorMsg("所有镜像请求均失败");
        }
    );

// 方式2:使用链式调用ambWith(),代码更简洁
userFromMirror1.ambWith(userFromMirror2)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(...); // 复用同上的订阅逻辑即可

额外优化:处理单个镜像请求失败的情况

如果某个镜像可能出现请求失败(比如宕机、网络超时),你可以给单个Single添加错误处理,避免因为一个镜像失败就直接触发整个amb的错误回调,而是让另一个镜像继续竞争:

Single<User> userFromMirror1 = Single.fromCallable(() -> mirrorApi1.getUserInfo())
    .subscribeOn(Schedulers.io())
    .onErrorResumeNext(throwable -> {
        // 镜像1请求失败,返回一个永远不会发射事件的Single,让镜像2继续执行
        return Single.never();
    });

这样如果镜像1失败,amb()会继续等待镜像2的结果,只有当两个镜像都失败时,才会触发最终的错误回调。


内容的提问来源于stack exchange,提问作者Thomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:53:22