【问题标题】:Tornado await for Future object to resolve龙卷风等待未来对象解决
【发布时间】:2018-11-30 00:17:40
【问题描述】:

我有一个处理程序,代码如下:

class HelloHandler(RequestHandler):

      routing_pattern = "/hello"

      async def get(self):

          url = 'some_url_here'
          request = httpclient.HTTPRequest(url=url, streaming_callback=self.on_chunk)
          result = await downloader.fetch(request)
          print(result)
          self.write("done")


      @gen.coroutine
      def on_chunk(self, chunk):
          self.write(chunk)
          yield self.flush()

这段代码调用了一个像这样定义的 async def 函数:

async def fetch(request):
    future = Future()
    await _qin.put(request)
    return future

我希望在我的处理程序中,事情会在 await downloader.fetch(request) 行停止,直到我为返回的未来设置一个值。现在这永远不会发生,所以事情应该停在那里。然而,似乎并没有真正期待未来。 print(result) 行显示一个“”,并且事情只是在该行之后加速。我究竟做错了什么 ?我怎样才能让功能停在那里并真正等待未来完成?一个附带问题......我在 on_chunk 方法中所做的是否正确?我想在那里等待刷新,但 streaming_callback 不采用异步函数。

【问题讨论】:

    标签: python async-await tornado


    【解决方案1】:

    我希望在我的处理程序中,事情会在 await downloader.fetch(request) 行停止,直到我为返回的未来设置一个值。

    你是对的。

    但是您的代码有问题。 Keep these points in mind*:

    1. 协程(async def 函数或 gen.coroutine 修饰函数)自动返回 Future
    2. 您从协程返回的任何内容都将包装在 Future 中。

    async def fetch(request) 函数中,您将返回一个 Future 对象。但是按照上面的规则 2,你的 Future 对象将被包裹在协程的 Future 对象中。

    所以,await downloader.fetch 没有暂停你的函数的原因是因为 fetch 协程自动返回的 Future 正在被立即解析。

    等待两次,您的代码应该可以按预期工作:

    result_future = await downloader.fetch(request)
    result = await result_future
    

    就个人而言,我发现双精度 await 有点不符合一般惯例。所以,我要做的是让fetch(request) 成为常​​规函数,而不是协程:

    def fetch(request):
        future = Future()
        # instead of running _qin.put yourself, 
        # ask the ioloop to run it
        ioloop.IOLoop.current().add_callback(_qin.put, request)
        return future
    

    如果您对使用双精度 await 感到满意,或者您必须对代码进行大量更改,则可以忽略这一点。


    *披露:链接的文章来自我自己的博客。

    【讨论】:

      猜你喜欢
      • 2017-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多