如何基于Twitch API与vert.x实现异步分页请求迭代查询
嘿,我来帮你搞定Vert.x异步环境下Twitch API分页查询的问题~
因为Vert.x是异步非阻塞的,普通的for循环根本没法用——循环会直接跑完,而API请求还没返回结果。咱们得用递归+异步回调的方式来串行处理每一页的请求,确保下一页的请求必须等上一页返回后再发起,完美适配Twitch的cursor分页逻辑。
解决方案思路
- 先改造你的
getLiveChannels方法,让它支持传入cursor参数,这样每次请求能带上上一页返回的游标。 - 新增一个递归的辅助方法,负责处理单页请求、合并数据,并且判断是否需要继续请求下一页。
- 在主方法里初始化总数据容器,启动第一页的查询,最后汇总所有数据返回。
完整代码示例
首先,调整getLiveChannels方法以支持cursor参数:
private void getLiveChannels(int limit, String cursor, Handler<AsyncResult<JsonObject>> handler) { WebClient client = WebClient.create(vertx); // 构建Twitch API请求,带上必要的请求头和参数 HttpRequest<Buffer> request = client.get("api.twitch.tv", "/helix/streams") .addQueryParam("first", String.valueOf(limit)) .putHeader("Client-ID", "你的Twitch ClientID") .putHeader("Authorization", "Bearer 你的Twitch Token"); // 如果有cursor,添加到请求参数里(对应Twitch API的after参数) if (cursor != null && !cursor.isEmpty()) { request.addQueryParam("after", cursor); } request.send(ar -> { if (ar.succeeded()) { HttpResponse<Buffer> response = ar.result(); if (response.statusCode() == 200) { handler.handle(Future.succeededFuture(response.bodyAsJsonObject())); } else { handler.handle(Future.failedFuture("API请求失败,状态码:" + response.statusCode())); } } else { handler.handle(Future.failedFuture(ar.cause())); } }); }
然后,改造你的getEntireStreamList方法,加上递归分页逻辑:
public void getEntireStreamList(Handler<AsyncResult<JsonObject>> handler) { JsonArray allStreamData = new JsonArray(); // 启动第一页查询,初始cursor为null fetchNextPage(null, allStreamData, handler); } // 递归辅助方法:处理单页请求,判断是否继续查询下一页 private void fetchNextPage(String cursor, JsonArray allData, Handler<AsyncResult<JsonObject>> finalHandler) { getLiveChannels(100, cursor, result -> { if (result.succeeded()) { JsonObject pageResult = result.result(); JsonArray pageData = pageResult.getJsonArray("data"); // 将当前页的数据追加到总数据中 pageData.forEach(item -> allData.add(item)); JsonObject pagination = pageResult.getJsonObject("pagination"); String nextCursor = pagination != null ? pagination.getString("cursor") : null; // 判断是否还有下一页:当前页满100条,且有有效cursor if (pageData.size() == 100 && nextCursor != null && !nextCursor.isEmpty()) { // 递归调用,获取下一页 fetchNextPage(nextCursor, allData, finalHandler); } else { // 所有页查询完成,返回汇总结果 JsonObject finalResult = new JsonObject().put("data", allData); finalHandler.handle(Future.succeededFuture(finalResult)); } } else { // 任何一页请求失败,直接返回错误中断流程 finalHandler.handle(Future.failedFuture(result.cause())); } }); }
关键说明
- 递归串行处理:每一页的请求都要等上一页返回后才发起,完全适配Vert.x的异步模型,不会出现请求乱序或者数据丢失的问题。
- 数据合并:用一个全局的
JsonArray来收集所有页的数据,避免每次请求覆盖之前的结果。 - 终止条件:当返回的数据少于100条(说明Twitch已经没有更多数据),或者没有有效的cursor时,就停止递归,返回最终汇总结果。
- 错误处理:如果任何一页请求失败,直接把错误传递给最终的handler,整个查询流程会立即中断。
额外注意事项
- 别忘了Twitch API有请求频率限制,要是请求太频繁可能会被限流,必要的话可以在递归调用前加个短暂延迟(比如用
vertx.setTimer)。 - 可以给请求加上超时配置,避免某个请求一直挂着导致整个流程卡住。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

