如何实现可异步迭代的分页API结果获取?
实现可直接异步遍历的分页结果类
你遇到的问题核心是混淆了同步迭代器和异步迭代器:Symbol.iterator是给同步遍历用的,它的next()方法必须返回同步的{value, done}对象,没法处理异步操作(比如你的fetch请求)。要实现for await...of的直接遍历,你需要实现的是异步迭代器,也就是Symbol.asyncIterator方法。
正确的实现方式
我们可以把你之前的生成器逻辑直接整合到Symbol.asyncIterator里,这样就能让Results实例直接支持for await...of遍历:
class Results { constructor(url, token) { this.url = url; this.token = token; } // 实现异步迭代器方法 async *[Symbol.asyncIterator]() { let currentUrl = this.url; while (true) { const response = await fetch(currentUrl, { headers: { 'Authorization': 'Bearer ' + this.token } }); const data = await response.json(); // yield 当前页的数据 yield data.values; // 没有下一页就终止迭代 if (!data.next) break; currentUrl = data.next; } } }
调用方式(完全符合你的理想用法)
const results = new Results('your-api-url', 'your-token'); for await (const page of results) { // 处理每一页的数据 console.log(page); }
为什么之前的Symbol.iterator不行?
同步迭代器的next()方法要求返回一个同步对象,而你的代码里next是异步函数,返回的是Promise,这不符合同步迭代器的规范。异步迭代器的next()方法才允许返回Promise(或者用生成器语法更简洁地实现),而for await...of就是专门用来遍历异步迭代器的语法。
额外说明
用async *生成器来实现Symbol.asyncIterator是最简洁优雅的方式,它自动帮你处理了异步状态和迭代终止的逻辑,比手动写一个返回迭代器对象的方式更易读和维护。
内容的提问来源于stack exchange,提问作者moose56
相关产品推荐
相关产品推荐

