这是我挣扎的事情,或者每当我这样做时,它似乎都很混乱。 我会以一种非常通用的方式提出这个问题,因为这不是我真正试图解决的问题。
我有一个API,我想从中消耗一些数据,例如通过:
def get_api_results(page)
results = HTTParty.get("api.api.com?page=#{page}")
end
当我打电话给它时,我可以检索一个总数。
results["total"] = 237
API限制了我在一次通话中可以检索的记录数量,比如说20个。所以我需要多次调用它。
我想做类似以下的事情,最好把它分成几块,这样我就可以使用像delayed_job..etc这样的东西
def get_all_api_pages
results = get_api_results(1)
total = get_api_results(1)["total"]
until page*20 > total do |p|
results += get_api_results(p)
end
end
每当我尝试解决这个问题时,我总是觉得我在写垃圾(而且我试图以多种方式解决它)。 例如,上面的内容让我受到API错误的支配,如果我在任何时候遇到错误,它会敲掉我收集的所有结果。
想知道是否只有一种通常良好,干净的方式来处理这种情况。
答案 0 :(得分:1)
我认为你没有那么干净......因为你只有在调用API后才收到总数。 你有没有尝试为此建立自己的枚举。它封装了丑陋的部分。这里有一些带有"模拟"的示例代码。 API:
class AllRecords
PER_PAGE = 50
def each
return enum_for(:each) unless block_given?
current_page = 0
total = nil
while total.nil? || current_page * PER_PAGE < total
current_page += 1
page = load_page(current_page)
total = page[:total]
page[:items].each do |item|
yield(item)
end
end
end
private
def load_page(page)
if page == 5
{items: Array.new(37) { rand(100) }, total: 237}
else
{items: Array.new(50) { rand(100) }, total: 237}
end
end
end
AllRecords.new.each.each_with_index do |item, index|
p index
end
你可以肯定地清理一下,但我认为这很好,因为它不会先收集所有物品。