据我从tornado.gen模块文档中了解到的是,tornado.gen.Task由tornado.gen.Callback和tornado.gen.Wait组成,每个回调/等待对都与唯一键相关联...

  @tornado.web.asynchronous
  @tornado.gen.engine
  def get(self):
      http_client = AsyncHTTPClient()
      http_client.fetch("http://google.com",
                        callback=(yield tornado.gen.Callback("google")))

      http_client.fetch("http://python.org",
                        callback=(yield tornado.gen.Callback("python")))

      http_client.fetch("http://tornadoweb.org",
                        callback=(yield tornado.gen.Callback("tornado")))
      response = yield [tornado.gen.Wait("google"), tornado.gen.Wait("tornado"), tornado.gen.Wait("python")]

      do_something_with_response(response)
      self.render("template.html")

因此,上面的代码将从不同的URL获取所有响应。
现在,我实际上需要完成的工作是在一个http_client返回数据后立即返回响应。因此,如果“tornadoweb.org”首先返回数据,则应执行self.write(respose),并且def get()中的循环应继续等待其他http_clients完成。
关于如何使用tornado.gen接口(interface)编写此代码的任何想法。

我试图做的非常模糊的实现(语法上不正确)将是这样的
class GenAsyncHandler2(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        http_client = AsyncHTTPClient()
        http_client.fetch("http://google.com",
                          callback=(yield tornado.gen.Callback("google")))

        http_client.fetch("http://python.org",
                          callback=(yield tornado.gen.Callback("python")))

        http_client.fetch("http://tornadoweb.org",
                          callback=(yield tornado.gen.Callback("tornado")))

        while True:
            response = self.get_response()
            if response:
                self.write(response)
                self.flush()
            else:
                break
        self.finish()


    def get_response(self):
        for key in tornado.gen.availableKeys():
            if key.is_ready:
                value = tornado.gen.pop(key)
                return value
        return None

最佳答案

是的,当您不应该使用inline callbacks,即gen时。
在所有回调完成后,还将调用self.render如果要部分返回服务器的响应,请部分渲染。

这样想(这是唯一有很大改进空间的想法):

  response = []
  @tornado.web.asynchronous
  def get(self):
      self.render('head.html')
      http_client = AsyncHTTPClient()

      http_client.fetch("http://google.com",
                        callback=self.mywrite)

      http_client.fetch("http://python.org",
                        callback=self.mywrite)

      http_client.fetch("http://tornadoweb.org",
                        callback=self.mywrite)

      self.render('footer.html')
      self.finish()


  def mywrite(self, result):
      self.render('body_part.html')
      self.response.add(result)
      if len(self.response) == 3:
        do_something_with_response(self.response)

关于python - Tornado异步HTTP增量返回结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11900634/

10-13 09:09