我有一个简单的aiohttp服务器,有两个处理程序。
第一个在async for
循环中进行一些计算。第二个只返回文本响应。not_so_long_operation
使用最慢的递归实现返回第30个fibonacci数,大约需要1秒的时间。在
def not_so_long_operation():
return fib(30)
class arange:
def __init__(self, n):
self.n = n
self.i = 0
async def __aiter__(self):
return self
async def __anext__(self):
i = self.i
self.i += 1
if self.i <= self.n:
return i
else:
raise StopAsyncIteration
# GET /
async def index(request):
print('request!')
l = []
async for i in arange(20):
print(i)
l.append(not_so_long_operation())
return aiohttp.web.Response(text='%d\n' % l[0])
# GET /lol/
async def lol(request):
print('request!')
return aiohttp.web.Response(text='just respond\n')
当我试图获取/
然后/lol/
时,只有当第一个完成时,它才会对第二个进行响应。
我做错了什么?如何让索引处理程序在每次迭代时释放ioloop?在
您的示例没有用于在任务之间切换的屈服点(
await
语句)。 异步迭代器允许在__aiter__
/__anext__
内使用await
,但不自动将其插入代码中。在说
应该像你期望的那样工作。在
在实际应用程序中,您很可能不需要
await asyncio.sleep(0)
调用,因为您将等待数据库访问和类似的活动。在这里并不需要异步迭代器。相反,您可以简单地将控件返回到循环中的事件循环。在Python3.4中,这是通过使用一个简单的
yield
来完成的:在Python3.5中,您可以定义一个
^{pr2}$Empty
对象,该对象的作用基本相同:然后使用
await
语法:或者简单地使用asyncio.sleep(0),即recently optimized:
也可以使用default executor在线程中运行
not_so_long_operation
:由于} (而不是
fib(30)
受CPU限制并且共享很少的数据,您可能应该使用^{ThreadPoolExecutor
):创建
^{pr2}$executor
时设置executor
:相关问题 更多 >
编程相关推荐