您的请求逻辑必须是异步的才能与EventMachine一起使用,我建议您使用em-http-request。你可以找到an example on how to use it here,它显示了如何并行运行请求。一个更好的并行运行多个连接的接口是来自同一个gem的MultiRequest class。
如果要排队的请求,只并行运行其中的一个固定数量,你可以做这样的事情:
EM.run do
urls = [...] # regular array with URLs
active_requests = 0
# this routine will be used as callback and will
# be run when each request finishes
when_done = proc do
active_requests -= 1
if urls.empty? && active_requests == 0
# if there are no more urls, and there are no active
# requests it means we're done, so shut down the reactor
EM.stop
elsif !urls.empty?
# if there are more urls launch a new request
launch_next.call
end
end
# this routine launches a request
launch_next = proc do
# get the next url to fetch
url = urls.pop
# launch the request, and register the callback
request = EM::HttpRequest.new(url).get
request.callback(&when_done)
request.errback(&when_done)
# increment the number of active requests, this
# is important since it will tell us when all requests
# are done
active_requests += 1
end
# launch three requests in parallel, each will launch
# a new requests when done, so there will always be
# three requests active at any one time, unless there
# are no more urls to fetch
3.times do
launch_next.call
end
end
买者自负,也很可能是一些细节我一直在错过上面的代码。
如果您认为在我的例子中很难遵循逻辑,欢迎来到编程平坦的世界。编写可读的代码是非常棘手的。这一切都倒退。有时它有助于从最后开始阅读。
我假设你不想在开始下载后添加更多的请求,它看起来不像你的问题中的代码,但如果你想要你可以重写我的代码到使用EM::Queue
而不是常规数组,并删除EM.stop
的部分,因为您不会停止。您可能会删除跟踪活动请求数量的代码,因为这不相关。最重要的部分将是这个样子:
launch_next = proc do
urls.pop do |url|
request = EM::HttpRequest.new(url).get
request.callback(&launch_next)
request.errback(&launch_next)
end
end
另外,请记住,我的代码实际上并没有做与响应什么。该响应将作为参数传递给when_done
例程(在第一个示例中)。我也为成功和错误做同样的事情,你可能不想在真正的应用程序中做。
伟大的解决方案,唯一的问题是when_done proc对launch_next proc不是已知的,所以您需要将它们写出来。至少这是对我有用的。 – Kitto 2011-10-11 16:21:29