python - 龙卷风等待未来对象解决
问题描述
我有一个带有以下代码的处理程序:
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 不采用异步函数。
解决方案
我希望在我的处理程序中,事情会在等待
downloader.fetch(request)
行上停止,直到我为返回的未来设置一个值。
你说的对。
但是你的代码有问题。请记住以下几点*:
- 协程(
async def
函数或gen.coroutine
修饰函数)会自动返回一个Future
. - 您从协程返回的任何内容都将被包装在 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
如果您对使用 double 感到满意await
,或者您必须对代码进行大量更改,则可以忽略这一点。
*披露:链接的文章来自我自己的博客。
推荐阅读
- c++ - 将 C++ 函数从 DLL 导出为 C 时调试和发布之间的区别
- user-permissions - 通过 MediaProjection 进行 ScreenCapture,无需用户干预 Kiosk 应用程序 - Android
- r - 闪亮的悬停只显示变量值
- python - Python:匹配具有多种模式的字符串
- google-cloud-platform - 如何禁用 DialogFlow 历史记录/日志?
- bash - 火花(纱线)远程应用程序提交bash
- flutter - 背景图像未设置,其显示在顶部
- python - Python 装饰器铸造检查器
- html - 在 html 代码中将两个表格对齐在一起
- c++ - 如何在c ++中使用对向量进行变换