import asyncio
import time


async def task1():
    print("Task1 begins")
    await asyncio.sleep(2)
    print("Task 1 is done")
    return "Task 1 is done!!"


async def task2():
    print("Task2 begins")
    await asyncio.sleep(1)
    print("Task 2 is done")
    return "Task 2 is done!!"


async def actually_no_async():
    task1_coroutine = task1()
    task2_coroutine = task2()
    #
    print("这样其实没有真正实现异步,该等的时间都还是等完了")
    #
    result1 = await task1_coroutine
    print(result1)
    result2 = await task2_coroutine
    print(result2)


async def wait_all():
    task1_coroutine = task1()
    task2_coroutine = task2()
    #
    print("执行asyncio.gather、asyncio.as_completed、asyncio.create_task中的一个,让协程开始调度")
    #
    for result in await asyncio.gather(task1_coroutine, task2_coroutine):
        print(result)


async def wait_any():
    task1_coroutine = task1()
    task2_coroutine = task2()
    #
    print("执行asyncio.gather、asyncio.as_completed、asyncio.create_task中的一个,让协程开始调度")
    #
    for coroutine in asyncio.as_completed([task1_coroutine, task2_coroutine]):
        result = await coroutine
        print(result)


async def wait_any2():
    print("执行asyncio.gather、asyncio.as_completed、asyncio.create_task中的一个,让协程开始调度")
    task1_future = asyncio.create_task(task1())
    task2_future = asyncio.create_task(task2())
    #
    done, pending = await asyncio.wait({task1_future, task2_future}, return_when=asyncio.FIRST_COMPLETED)
    for future in done:
        print(future.result())


async def schedule_tasks():
    task1_coroutine = task1()
    task2_coroutine = task2()
    #
    print("执行asyncio.gather、asyncio.as_completed、asyncio.create_task中的一个,让协程开始调度")
    # 不写asyncio.create_task的话协程只是放在任务队列里面,并不会执行
    # asyncio.gather和asyncio.as_completed会等待直到所有(任意)任务完成
    # 只有asyncio.create_task可以让协程现在就开始运行,却又不等待任何协程结束就可以执行下一条命令
    future1 = asyncio.create_task(task1_coroutine)
    future2 = asyncio.create_task(task2_coroutine)

    result1 = await future1
    print(result1)
    result2 = await future2
    print(result2)


def task3():
    print("Task3 begins")
    time.sleep(2)
    print("Task 3 is done")
    return "Task 3 is done!!"


def task4():
    print("Task4 begins")
    time.sleep(1)
    print("Task 4 is done")
    return "Task 4 is done!!"


async def to_thread():
    task3_coroutine = asyncio.to_thread(task3)
    task4_coroutine = asyncio.to_thread(task4)
    #
    print("to_thread只有python3.9以上可用,可以用协程包装线程")
    #
    for result in await asyncio.gather(task3_coroutine, task4_coroutine):
        print(result)


asyncio.run(actually_no_async())
asyncio.run(wait_all())
asyncio.run(wait_any())
asyncio.run(wait_any2())
asyncio.run(schedule_tasks())
asyncio.run(to_thread())