我有一个协同程序,是越来越大,我想分裂它的可读性。你知道吗
async def handle_message(self, message):
message_type = message.get('type')
if message_type == 'broadcast':
...
for n in self._neighbors:
await self.send_message(n, message)
elif message_type == 'graph':
...
我想将处理广播消息的部分提取到一个私有方法中,如下所示:
async def handle_message(self, message):
message_type = message.get('type')
...
if message_type = 'broadcast':
await self._handle_broadcast(message)
elif message_type = 'graph':
...
问题是,这会改变代码的行为,因为_handle_broadcast
部分是一个协程,而且它的执行可能会延迟,因为我用await
调用它。你知道吗
如何确保协同程序立即运行并且不被延迟?你知道吗
简而言之:使用
await
,完全按照开始的方式拆分协同程序。你知道吗不管是好是坏,这个前提是错误的。当给定一个协程时,
await
立即开始执行它,没有中间延迟。只有如果协同程序调用某个导致它挂起的东西(例如asyncio.sleep
或一个还没有数据的网络读取),您的协同程序才会随之挂起—这正是代码保持内联时您将得到的结果。你知道吗从这个意义上说,
await <some coroutine>
的工作方式类似于常规函数调用的协同程序,它允许您所需要的那种不改变语义的重构。这可以用一个例子来说明:上面的代码阻塞了事件循环—即使
coro
除了循环中的await
之外什么都不做。因此await
并不能保证屈服于事件循环,协同程序必须用其他方法来完成。(此行为也可能是bugs的来源。)在上面的例子中,可以通过插入一个
await asyncio.sleep(0)
来“解除”事件循环。但是在生产异步代码中不应该需要这种东西,在这种代码中,程序的结构应该使每个协同程序所做的工作相对较少,然后使用await
来获取更多的数据。你知道吗相关问题 更多 >
编程相关推荐