5

これが私のコードです:

EventMachine.run {

    conn = EM::Protocols::HttpClient2.connect request.host, 80

    req = conn.get(request.query)
    req.callback { |response|
      p(response.status)
      p(response.headers)
      p(response.content)
    }
}

コールバックが発生します。つまり、ステータスなどの文字列出力を取得します。

しかし、私がやりたいのは、コールバックを起動してから繰り返すことです。毎回 URL を微調整するなど、実装する予定のロジックは他にもありますが、今のところは、次のようにしたいだけです。

  1. URL を取得する
  2. コールバックを起動する
  3. 繰り返す...

このパターンについての私の理解は、そのループ内のすべてが発火し、その後戻り、その後、EM.stop.

現在、URL データを取得していますが、ハングしているように見えます。

ここで続行するには、なんらかの返品が必要ですか? ハングしていて、何度もループしていないのはなぜですか?

上記のコードブロック全体をループ do ... end で囲むと、期待どおりに動作します..これを実装する正しい方法ですか? EM.run完了するとすべてが繰り返されると思っていたので、混乱していると思います。

4

1 に答える 1

4

指定したrunブロックは 1 回だけ実行されます。イベント ループは直接公開されませんが、見えないように意図されたものです。runブロックとwhileループを混同しないでください。一度だけ実行されますが、イベント ループの実行中に実行されます。

操作を繰り返したい場合は、何らかのスタックを作成してそれを処理する必要があります。各コールバックは、他に行う作業があるかどうかスタックをチェックしてから、別の呼び出しを発行します。EventMachine アプリケーションは、このコールバック チェーン メソッドを使用して構築されます。

次のようなものを実装する必要があります。

def do_stuff(queue, request = nil)
  request ||= queue.pop
  return unless (request)

  conn = EM::Protocols::HttpClient2.connect request.host, 80

  req = conn.get(request.query)
  req.callback { |response|
    p(response.status)
    p(response.headers)
    p(response.content)

    EventMachine.next_tick do
      # This schedules an operation to be performed the next time through
      # the event-loop. Usually this is almost immediate.
      do_stuff(queue)
    end
  }
end   

イベント ループ内で、このチェーンをキックします。

EventMachine.run do
  queue = [ ... ] # List of things to do
  do_stuff(queue)
end

EventMachine がどのように機能するかを理解すれば、おそらくこれを実装するためのより洗練された方法を見つけることができるでしょう。

于 2012-08-20T02:28:00.510 に答える