You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从同步函数调用asyncio时打印输出顺序不符合预期问题求解

问题原因

你遇到的输出顺序不符合预期的核心原因是对await的执行逻辑理解有误:

  • 在异步协程中,await 协程对象的作用是挂起当前协程,等待被调用的协程完全执行完毕后,才会继续执行当前协程的后续代码,并非将协程提交到事件循环后就立即执行后续逻辑。

你的main_async是顺序调用await foo()、await bar(),执行流程完全是串行的:

  1. 先执行foo协程,打印before the sleep,遇到await asyncio.sleep(2)后挂起2秒
  2. 2秒后foo唤醒,打印world,foo协程执行完毕,返回main_async
  3. 才开始执行bar协程,打印hello
    因此最终输出顺序是before the sleep → world → hello,和你实际运行的结果一致。
预期效果实现方案

如果要让foo和bar并发执行,得到你想要的输出顺序,需要先将两个协程封装为异步任务提交到事件循环,再统一等待执行完成,示例代码如下:

import asyncio

def main():
    asyncio.run(main_async())

async def main_async():
    # 先创建异步任务,提交到事件循环后立即返回,不会等待任务执行完成
    task_foo = asyncio.create_task(foo())
    task_bar = asyncio.create_task(bar())
    # 等待所有任务执行完成
    await task_foo
    await task_bar
    # 也可以用asyncio.gather简化写法:await asyncio.gather(foo(), bar())

async def foo():
    print('before the sleep')
    await asyncio.sleep(2)
    print('world')

async def bar():
    print('hello')
    await asyncio.sleep(0)

if __name__=='__main__':
    main()

上述代码的执行流程:

  1. main_async运行后先创建foo任务,foo立即执行打印before the sleep,遇到sleep(2)后挂起,控制权交回main_async
  2. main_async继续创建bar任务,bar立即执行打印hello,遇到sleep(0)后挂起,控制权交回main_async
  3. 等待2秒后foo唤醒,打印world,所有任务执行完成
    最终输出完全符合你的预期:

before the sleep
hello
world

内容的提问来源于stack exchange,提问作者darren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 17:36:02