我有一个带有两个处理程序的简单aiohttp服务器。 第一个在 async for 循环中进行一些计算。第二个只是返回文本响应。 not_so_long_operation 返回第30个斐波那契数,其递归实现最慢,大约需要一秒钟的时间。
I have a simple aiohttp-server with two handlers. First one does some computations in the async for loop. Second one just returns text response. not_so_long_operation returns 30-th fibonacci number with the slowest recursive implementation, which takes something about one second.
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?
When I'm trying to fetch / and then /lol/, it gives me response for the second one only when the first one gets finished. What am I doing wrong and how to make index handler release the ioloop on each iteration?
推荐答案您的示例没有 yield点(等待语句)以在任务之间进行切换。 异步迭代器允许在 __ aiter __ / <$ c $中使用 await c> __ anext __ ,但不要将其自动插入代码中。
Your example has no yield points (await statements) for switching between tasks. Asynchronous iterator allows to use await inside __aiter__/__anext__ but don't insert it automatically into your code.
说,
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: await asyncio.sleep(0) # insert yield point return i else: raise StopAsyncIteration应该按预期工作。
在实际应用中很可能不需要等待asyncio.sleep(0)调用,因为您将等待数据库访问和类似的活动。
In real application most likely you don't need await asyncio.sleep(0) calls because you will wait on database access and similar activities.
更多推荐
Python 3.5异步用于阻止ioloop
发布评论