无事水,但要好好学习
Not
|

Nolca

园龄:6年9个月粉丝:12关注:9

python网络编程:一边延迟启动,一边准备as_completed

原代码:

import asyncio as aio
async def Sleeper(s=1):
t = f'Sleeper for {s} seconds'
await aio.sleep(s)
print(t)
return t
async def main():
tasks = [Sleeper(1.1), Sleeper(1)]
async def sub():
nonlocal tasks
for i in range(len(tasks)):
tasks[i] = aio.create_task(tasks[i])
if i < len(tasks) - 1:
await aio.sleep(10) # 阻塞!
await sub()
for t in aio.as_completed(tasks):
text = await t # 等不到
print('✅ ' + text)
aio.run(main())

这会有性能问题,sub()会阻塞下方的aio.as_complted的执行!

deepseek解决方案

import asyncio as aio
async def Sleeper(s=1):
t = f'Sleeper for {s} seconds'
await aio.sleep(s)
print(t)
return t
async def main():
tasks = [Sleeper(1.1), Sleeper(1)]
async def process_task(task):
text = await task
print('✅ ' + text)
async def sub():
for i in range(len(tasks)):
# 创建任务并立即启动处理协程
task = aio.create_task(tasks[i])
aio.create_task(process_task(task))
# 除最后一个任务外,每个任务创建后等待10秒
if i < len(tasks) - 1:
await aio.sleep(10)
await sub()
aio.run(main())

其实就是js里.then()的曲折实现

真正解决方案

async def task_1by1(
coros: List[Coroutine],
callback: Callable[[aio.Task], object] = None,
duration=RELAX
):
"""
Run tasks one by one with a duration of `duration` seconds
- callback: accept `Task` object as argument only
```python
def callback(task: asyncio.Task[TYPE_OF_RETURN]):
if task.cancelled():
msg = "Download cancelled"
raise Exception(msg)
t = task.result()
return t
```
"""
tasks = []
for i in range(len(coros)):
c = coros[i]
t = aio.create_task(c)
if callback and callable(callback):
t.add_done_callback(callback)
tasks.append(t)
if i < len(coros) - 1:
await aio.sleep(duration)
results = await aio.gather(*tasks)
return results

本文作者:Nolca

本文链接:https://www.cnblogs.com/nolca/p/18748861

版权声明:本作品采用 收益分享revenue sharing 许可协议进行许可。

posted @   Nolca  阅读(8)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 ⏩intro 山姆精
  2. 2 🎸吉他 马叉
  3. 3 ☁升调 山姆精
  4. 4 🐦Flutter Virtual Riot/Madi
  5. 5 🎶纯律 山姆精
  6. 6 👻yeah~Color Bass! VR
🎸吉他 - 马叉
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.