【问题标题】:Ruby EventMachine - how to return values from EM::Deferrable to main EM loop?Ruby EventMachine - 如何将值从 EM::Deferrable 返回到主 EM 循环?
【发布时间】:2011-12-16 03:41:22
【问题描述】:

我玩 EventMachine 有几天了,恕我直言,学习曲线陡峭;-) 我尝试通过触发回调中需要的 HttpHeaderCrawler.query() 来返回哈希。但我在这种情况下得到的不是哈希 {'http_status' => xxx, 'http_version' => xxx} 而是 EventMachine::HttpClient 对象本身。

我想保持 EM.run 块干净,并想在自己的类/模块中执行所有逻辑,那么如何将这样的值返回到主循环中以通过回调访问它?非常感谢;-)

#!/usr/bin/env ruby

require 'eventmachine'
require 'em-http-request'

class HttpHeaderCrawler
  include EM::Deferrable

  def query(uri)
    http = EM::HttpRequest.new(uri).get
    http.callback do
      http_header = {
        "http_status" => http.response_header.http_status,
        "http_version" => http.response_header.http_version
      }
      puts "Returns to EM main loop: #{http_header}"
      succeed(http_header)
    end
  end
end

EM.run do
  domains = ['http://www.google.com', 'http://www.facebook.com', 'http://www.twitter.com']
  domains.each do |domain|
    hdr = HttpHeaderCrawler.new.query(domain)
    hdr.callback do |header|
      puts "Received from HttpHeaderCrawler: #{header}"
    end
  end
end

这个 sn-p 产生以下输出:

Returns to EM main loop: {"http_status"=>302, "http_version"=>"1.1"}
Received from HttpHeaderCrawler: #<EventMachine::HttpClient:0x00000100d57388>
Returns to EM main loop: {"http_status"=>301, "http_version"=>"1.1"}
Received from HttpHeaderCrawler: #<EventMachine::HttpClient:0x00000100d551a0>
Returns to EM main loop: {"http_status"=>200, "http_version"=>"1.1"}
Received from HttpHeaderCrawler: #<EventMachine::HttpClient:0x00000100d56280>

【问题讨论】:

  • 我喜欢 this tutorial by Martyn Loughran 建议避免“意大利面条回调代码”的方法。
  • 是的,我知道这个教程。从 EM 开始的好方法。但我不明白的是:Martyn 在他的 em-http-request 样本中返回一个值,就像我在上面的 sn-p 中所做的一样。看不到我的情况出了什么问题
  • 这很奇怪。用 HttpHeaderCrawler 中的 initialize(uri) 替换 query(uri) 和 hdr = HttpHeaderCrawler.new(domain) 替换 hdr = HttpHeaderCrawler.new.query(domain) 可以解决所有问题。但为什么呢?
  • 我发现的唯一区别是他的代码使用了self.succeed()self.fail(),而你的代码省略了self.。这足以造成问题吗?

标签: ruby callback eventmachine


【解决方案1】:

我认为问题是#query返回http.callback,它返回http对象本身,而它应该返回self,即HttpHeaderCrawler。看看这是否有效。

def query(uri)
  http = EM::HttpRequest.new(uri).get
  http.callback do
    http_header = {
      "http_status" => http.response_header.http_status,
      "http_version" => http.response_header.http_version
    }
    puts "Returns to EM main loop: #{http_header}"
    succeed(http_header)
  end
  self
end

【讨论】:

  • 嘿,埃里克。酷,这正是我麻烦的原因。现在一切正常ö谢谢:)
猜你喜欢
  • 2011-12-12
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-23
  • 2014-11-05
  • 2023-03-11
相关资源
最近更新 更多