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

如何用WebClient非阻塞实现:过滤非Fork仓库并提取Mono<Branch[]>中的Branch[]

WebClient实现GitHub非Fork仓库及分支列表获取方案

针对你遇到的两个问题,直接给出解决方案:

1. 过滤非Fork仓库

不需要先将响应赋值给变量再过滤,直接在getRepos返回的Flux<Repo>上使用filter操作符即可,过滤掉fork为true的仓库:

private Flux<Repo> getRepos(String username) {
    return webClient
            .get()
            .uri("/users/{username}/repos", username)
            .retrieve()
            .bodyToFlux(Repo.class)
            // 过滤非Fork仓库,同时处理fork字段为null的边界情况
            .filter(repo -> repo.fork() == null || !repo.fork());
}

这里用URI模板{username}代替字符串拼接,更规范且避免潜在的语法问题。

2. 从Mono<Branch[]>提取数据构建ResponseRepo

getBranches返回的是异步类型Mono<Branch[]>,不能同步提取值。需要通过zip操作将当前仓库的信息与分支数据异步组合,再映射为ResponseRepo:

修改getReposInfo方法如下:

public Flux<ResponseRepo> getReposInfo(String username) {
    return getRepos(username)
            .flatMap(repo -> Mono.zip(
                    Mono.just(repo),
                    getBranches(username, repo.name())
            ).map(tuple -> new ResponseRepo(
                    tuple.getT1().name(),
                    tuple.getT1().owner().login(),
                    tuple.getT2()
            )));
}

Mono.zip会等待两个异步操作完成后,将结果封装为元组,再通过map转换为目标对象。

完整修改后的代码

@Service
public class RepoServiceImpl implements RepoService {

    private final WebClient webClient;

    public RepoServiceImpl(WebClient.Builder builder) {
        this.webClient = builder.baseUrl("https://api.github.com").build();
    }

    public Flux<ResponseRepo> getReposInfo(String username) {
        return getRepos(username)
                .flatMap(repo -> Mono.zip(
                        Mono.just(repo),
                        getBranches(username, repo.name())
                ).map(tuple -> new ResponseRepo(
                        tuple.getT1().name(),
                        tuple.getT1().owner().login(),
                        tuple.getT2()
                )));
    }

    private Flux<Repo> getRepos(String username) {
        return webClient
                .get()
                .uri("/users/{username}/repos", username)
                .retrieve()
                .bodyToFlux(Repo.class)
                .filter(repo -> repo.fork() == null || !repo.fork());
    }

    private Mono<Branch[]> getBranches(String username, String repo) {
        return webClient
                .get()
                .uri("/repos/{username}/{repo}/branches", username, repo)
                .retrieve()
                .bodyToMono(Branch[].class);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:46:03