我必须使用外部API来生成屏幕截图。在第一步中,我触发生成屏幕截图并收到job_id
。我必须等待并且可以下载给定job_id
的屏幕截图。不幸的是,我不知道我需要等多久。有时结果在10秒后就绪,有时则没有。如果尚未就绪,则函数image_url/1
将返回nil
。如果已准备就绪,则返回图像URL。
目前我使用睡眠时间为45秒,这是次优的。
我不明白如何使用递归的概念来实现函数generate_screenshot/1
,首先运行new_job_id(url)
,然后尝试image_url/1
10次,10秒在nil
之间或之前睡觉。
如何通过递归来解决这个问题?
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
答案 0 :(得分:2)
您应该可以使用模式匹配和稍微分解逻辑来实现。这样的事情应该有效:
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
,并使用count变量匹配第10个响应。
希望这有用,我想发表评论并询问更多信息,但我还不能发表评论。
答案 1 :(得分:0)
首先,我不明白你为什么要/必须使用递归。
恕我直言,一个优雅的方法是制作一个检查 image_url 的循环,如果图像没有准备好,则睡眠固定的秒数(2,5,10,......?)然后继续循环(在n秒内再次检查)并在图像准备好时停止循环。
此解决方案是否满足您的需求?