龙卷风等待未来对象解决
Tornado await for Future object to resolve
我有一个具有以下代码的处理程序:
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()
此代码调用如下定义的异步 def 函数:
async def fetch(request):
future = Future()
await _qin.put(request)
return future
我希望在我的处理程序中,事情会停止在 await downloader.fetch(request) 行,直到我为返回的 future 设置一个值。现在这永远不会发生,所以事情应该就此停止。然而,似乎并没有真正等待未来。 print(result) 行显示一个“”,并且事情只是通过那条线加速。我究竟做错了什么 ?我怎样才能让功能停在那里并真正等待未来完成?附带问题...我在 on_chunk 方法中所做的是否正确?我想等待刷新在那里发生,但 streaming_callback 不采用异步功能。
I was hoping that inside my handler, things will stop on the await downloader.fetch(request)
line until I set a value on the returned future.
你是对的。
但是你的代码有问题。 Keep these points in mind*:
- 协程(
async def
函数,或 gen.coroutine
装饰函数)自动 return 一个 Future
。
- 你从协程中 return 得到的任何东西,都会被包裹在 Future 中。
在 async def fetch(request)
函数中,您正在 return 创建一个 Future 对象。但是根据上面的规则 2,您的 Future 对象将被包装在协程的 Future 对象中。
所以,await downloader.fetch
没有暂停你的函数的原因是因为由 fetch
协程自动 returned 的 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
,或者如果您必须对代码进行大量更改,则可以忽略它。
*披露:链接文章来自我自己的博客。
我有一个具有以下代码的处理程序:
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()
此代码调用如下定义的异步 def 函数:
async def fetch(request):
future = Future()
await _qin.put(request)
return future
我希望在我的处理程序中,事情会停止在 await downloader.fetch(request) 行,直到我为返回的 future 设置一个值。现在这永远不会发生,所以事情应该就此停止。然而,似乎并没有真正等待未来。 print(result) 行显示一个“”,并且事情只是通过那条线加速。我究竟做错了什么 ?我怎样才能让功能停在那里并真正等待未来完成?附带问题...我在 on_chunk 方法中所做的是否正确?我想等待刷新在那里发生,但 streaming_callback 不采用异步功能。
I was hoping that inside my handler, things will stop on the await
downloader.fetch(request)
line until I set a value on the returned future.
你是对的。
但是你的代码有问题。 Keep these points in mind*:
- 协程(
async def
函数,或gen.coroutine
装饰函数)自动 return 一个Future
。 - 你从协程中 return 得到的任何东西,都会被包裹在 Future 中。
在 async def fetch(request)
函数中,您正在 return 创建一个 Future 对象。但是根据上面的规则 2,您的 Future 对象将被包装在协程的 Future 对象中。
所以,await downloader.fetch
没有暂停你的函数的原因是因为由 fetch
协程自动 returned 的 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
,或者如果您必须对代码进行大量更改,则可以忽略它。
*披露:链接文章来自我自己的博客。