【问题标题】:Recursion to call an external API递归调用外部 API
【发布时间】:2023-03-23 15:43:02
【问题描述】:

我必须使用外部 API 来生成屏幕截图。在第一步中,我触发屏幕截图的生成并收到job_id。比我必须等待并且可以使用给定的job_id 下载屏幕截图。不幸的是,我不知道我要等多久。有时结果会在 10 秒后准备好,有时则不然。如果它没有准备好,函数image_url/1 返回nil。如果它准备好了,它会返回图像 URL。

目前我使用睡眠 45 秒,这是次优的。

我不明白如何使用递归的概念来实现函数generate_screenshot/1,首先运行new_job_id(url),然后尝试image_url/1 10 次,其间或直到它不是@ 987654329@.

如何通过递归解决这个问题?

def generate_screenshot(url) do
  job_id = new_job_id(url)
  :timer.sleep(45000)

  image_url(job_id)
end

defp new_job_id(url) do
  # This function triggers a process on 
  # an external web server an returns 
  # the job_id of it.
  12345
end

defp image_url(job_id) do
  # This function fetches something from 
  # a webserver. The result is nil or 
  # a URL of an image.
  [...]
end

【问题讨论】:

标签: elixir phoenix-framework


【解决方案1】:

您应该能够使用模式匹配并稍微分解您的逻辑来做到这一点。这样的事情应该可以工作:

def generate_screenshot(url) do
  job_id = new_job_id(url)

  image_url(job_id))
end

defp new_job_id(url) do
  # This function triggers a process on 
  # an external web server an returns 
  # the job_id of it.
  12345
end

defp image_url(job_id) do
  # Call the version of this function with arity /2
  # and check the result. The 0 will act as a counting variable
  image_url(job_id), 0)
end

# When the counter reaches 10 return the value regardless
defp image_url(_, 10) do fetch_something()

# Add a case statement that checks the value returned
# if its nil call image_url/2 again after 10 seconds 
# and increment the counter by 1 
# Otherwise its not nil so we return the value
defp image_url(job_id, count) do
  case fetch_something() do
    nil -> 
      :timer.sleep(10000)
      image_url(job_id, count + 1) 
    url -> url
  end
end

defp fetch_something() do
  # This function fetches something from 
  # a webserver. The result is nil or 
  # a URL of an image.
  [...]
end

这里的重要部分是我们从image_url/2 函数中分离出实际的内容获取,现在可以从case 语句中调用它。这让我们可以使用模式匹配来调用 image_url/2 并在第 10 个响应中匹配 count 变量。

希望这有帮助我想发表评论并询问更多信息,但我还不能离开 cmets。

【讨论】:

    【解决方案2】:

    首先我不明白你为什么想要/必须使用递归。

    恕我直言,一个优雅的方法是创建一个循环来检查 image_url,如果图像尚未准备好,则休眠固定的秒数(2、5、10,...?)然后继续循环(在 n 秒内再次检查)并在图像准备好时停止循环。

    此解决方案是否满足您的需求?

    【讨论】:

    猜你喜欢
    • 2021-02-06
    • 2018-01-30
    • 2014-09-28
    • 2017-10-28
    • 1970-01-01
    • 2019-01-22
    • 2018-06-26
    • 1970-01-01
    • 2021-05-12
    相关资源
    最近更新 更多