簡體   English   中英

從API獲取所有頁面

[英]Getting all the pages from an API

這是我掙扎的事情,或者每當我這樣做時,它似乎都很混亂。 我將以非常通用的方式提出這個問題,因為這不是我真正想要解決的問題。

我有一個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錯誤的支配,如果我在任何時候遇到錯誤,它會敲掉我收集的所有結果。

想知道是否只有一種通常良好,干凈的方式來處理這種情況。

我認為你不能那么干凈......因為你只有在調用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

你可以肯定地清理一下,但我認為這很好,因為它不會首先收集所有項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM