переписать синхронизацию как асинхронный: не ждать в функции - PullRequest
0 голосов
/ 09 июля 2019

Когда я читаю больше, я чувствую себя более глупо из-за aysnc в python.Поэтому я решил попросить прямой ответ.Как я могу изменить следующий код (используя асинхронный или аналогичный подход) для достижения желаемого результата?Кроме того, как я могу сделать это в колбе или в санике?

import time

def long_job():
    print('long job started')
    time.sleep(5)
    print('long job ended')

def main_job():
    long_job()
    time.sleep(1)
    print('main job returned')

main_job()

# expected result:
# 'long job started'
# 'main job returned'
# 'long job ended'

По сути, я НЕ хочу, чтобы ждал окончания long_job перед возвратом моего main_job.Заранее спасибо.:)

1 Ответ

2 голосов
/ 09 июля 2019

Ждите asyncio sleep(), чтобы уступить время другим работам (если вам не нужно ждать чего-то другого).Используйте create_task() вместо await, чтобы начать работу без блокировки.Наконец, вы должны запустить основную работу, используя цикл обработки событий.

# Written in Python 3.7
import asyncio

async def long_job():
    print('long job started')
    await asyncio.sleep(5)
    print('long job ended')

async def main_job():
    asyncio.create_task(long_job())
    await asyncio.sleep(1)
    print('main job returned')

Ваша структура должна запустить цикл обработки событий, вам не нужно запускать его самостоятельно.Вы можете await или вызвать create_task на main_job() из функции async def, вызываемой вашей платформой, в зависимости от того, хотите ли вы блокировать или нет.


Если вы хотите проверить этобез фреймворка вам придется самостоятельно запускать цикл, используя asyncio.run().Это прекратится сразу после завершения задачи, даже если другие задачи еще не завершены.Но это достаточно легко обойти:

async def loop_job():
    asyncio.create_task(main_job())
    while len(asyncio.Task.all_tasks()) > 1:  # Any task besides loop_job()?
        await asyncio.sleep(0.2)

asyncio.run(loop_job())

Если вы сами реализуете фреймворк, вы можете использовать более примитивный loop.run_forever(), но вам придется stop() сделать это самостоятельно.

...