调用协程并在asyncio.Protocol.data中获得未来
我需要在asyncio循环内获得未来的结果,它类似于从asyncio.Protocol.data_received调用协程
但是asyncio
和PY34中的asyncio是完全不同的,下面是可以在PY34中正确运行的代码,但是在PY35中,它将在yield from
停顿并从不返回。
# PY34
class RelayClient(asyncio.Protocol):
pass
class Server(asyncio.Protocol):
def data_received(self, data):
# I need to connect to another address, and get future result at current function.
# Also I could not run loop.run_until_complete().
loop = asyncio.get_event_loop()
result = yield from loop.create_connection(RelayClient, 'www.google.com', 443)
do_some_thing_with_result(result)
那么,如何在python 3.5中做到这一点?
任何建议表示赞赏。
您不能等待来自不是协程的函数的协程。 data_received
不是协程,所以在注释中提到,您需要使用ensure_future
helper从协同程序创建“背景”任务。
不需要开始使用回调:
async def do_stuff(data):
result = await loop.create_connection(RelayClient, 'www.google.com', 443)
await do_some_thing_with_result(result)
class Server(asyncio.Protocol):
def data_received(self, data):
asyncio.ensure_future(do_stuff(data))
然而,我会指出,asyncio不会给您带来任何数据,因为data_received
将被您期望的完整数据调用。 通常你在Protocol
看到的模式看起来很像这样:
async def process_line(line):
...
class Server(asyncio.Protocol):
def __init__(self):
self.buffer = b''
def data_received(self, data):
self.buffer += data
if b'n' not in self.buffer:
return
line, self.buffer = self.buffer.split(b'n')
fut = asyncio.ensure_future(process_line(line))
fut.add_done_callback(self._handle_exception)
def _handle_exception(self, fut):
if fut.exception() is not None:
print('Processing failed', fut.exception())
(这只是一个例子,它复制缓冲区的方式太多了,而且在大多数生产用例中效率很低)
链接地址: http://www.djcxy.com/p/53231.html上一篇: Calling coroutine and getting future in asyncio.Protocol.data
下一篇: Conditional in a coroutine based on whether it was called again?