既存の EventMachine::Deferrable なクラスを薄くラップする
本格的に Deferrable なクラスを作りたいときは include EM::Deferrable するけど,そうではなく既存の Deferrable の上にちょっと乗せるだけみたいなときは EM::DefaultDeferrable を利用するといいらしい.
em-http-request を利用して非同期にリクエストを投げ,結果を Nokogiri でパースして例えばタイトルを表示する例.こんなかんじでいいんだろうか.
#!/usr/bin/ruby # coding: utf-8 require 'em-http' require 'nokogiri' class HtmlDocument < EM::DefaultDeferrable attr_reader :http, :parser def initialize(http) @http = http end def succeed @parser = Nokogiri::HTML.parse @http.response super end end def get_document(uri) http = EM::HttpRequest.new(uri).get doc = HtmlDocument.new http http.callback { doc.succeed } http.errback { doc.fail } doc end EM.run do multi = EM::MultiRequest.new [ 'http://www.google.co.jp/', 'http://www.hatena.ne.jp/h/o/g/e', 'http://eagletmt.com/', ].each do |uri| doc = get_document uri doc.callback do puts "ok: #{doc.http.response_header.status}: #{doc.parser.xpath('//title').inner_text}" end doc.errback do puts "ng: #{doc.http.error}: #{doc.http.uri}" end multi.add doc end multi.callback do puts "succeeded #{multi.responses[:succeeded].size}/#{multi.requests.size}" EM.stop end end
実行結果(最後の行以外の順番はバラつく可能性あり)
ng: unable to resolve server address: http://eagletmt.com:80/ ok: 200: Google ok: 404: おさがしのページは見つかりませんでした - はてな succeeded 2/3