当结果返回空数组时,使用带有 break 语句的无条件循环。
i = 1
loop do
result = call_to_api(i)
do_something_with(result)
i += 1
break if result.empty?
end
当然,在生产场景中,您需要一些更健壮的东西,包括异常处理程序、一些进度日志报告和某种具体的迭代限制,以确保循环不会变得无限。
更新
这是一个使用类来包装逻辑的示例。
class Api
DEFAULT_OPTIONS = {:start_position => 1, :max_iterations => 1000}
def initialize(base_uri, config)
@config = DEFAULT_OPTIONS.merge(config)
@position = config[:start_position]
@results_count = 0
end
def each(&block)
advance(&block) while can_advance?
log("Processed #{@results_count} results")
end
def advance(&block)
yield result
@results_count += result.count
@position += 1
@current_result = nil
end
def result
@current_result ||= begin
response = Net::HTTP.get_response(current_uri)
JSON.decode(response.body)
rescue
# provide some exception handling/logging
end
end
def can_advance?
@position < (@config[:start_position] + @config[:max_iterations]) && result.any?
end
def current_uri
Uri.parse("#{@base_uri}?page=#{@position}")
end
end
api = Api.new('http://somesite.com/api/v1/resource')
api.each do |result|
do_something_with(result)
end
通过为每个线程设置启动和迭代计数,这也有一个角度允许并发,这将通过并发 http 请求明确地加快这一速度。