как не дожидаться окончания асинхронной функции
Делаю бота для игры в мафию, и чтобы завершить ночь должно либо пройти 90 секунд, либо когда все сделают свои ночные действия
@game_process_router.callback_query(CallbackFactory.filter())
async def night_actions_handler(callback: CallbackQuery, callback_data: CallbackFactory):
#какая-то логика
...
#какая-то логика
global night_callbacks
night_callbacks += 1
if(night_callbacks == len(registration.live_players)):
await bot.send_message(chat_id = registration.game_chat_id, text = f"Город просыпается")
await callback.answer()
я понимаю что нужно использовать await asyncio.sleep(90)
но если игроки нажмут свои действия раньше 90с то как сказать питону чтобы он не ждал эти 90
Ответы (3 шт):
То, что вы хотите, можно реализовать через таймеры в apscheduler
. Создайте задачу на выполнение через 90 секунд, которая прервёт ночь. При этом aiogram
будет продолжать работать дальше и вы сможете обрабатывать события от игроков. И как только все нажмут свои кнопки раньше 90 секунд, вы сможете немедленно выполнить и удалить отложенную задачу по ID или из JobStore'а (job.remove
, job.func(*job.args, **job.kwargs)
).
Делай массив questions из asyncio.Future() на каждый вопрос пользователю.
Дожидайся через
done, pending = await asyncio.wait(questions, timeout=90)
В done будут отмеченные, в pending просроченные.
Установить ответ в Future например через fu.set_result({"user":id, "answer": data})
Всё, я со всем разобрался:
trigger = DateTrigger(run_date=datetime.now() + timedelta(seconds = 90))
global job
job = apscheduler.add_job(func = stop_night_func, trigger=trigger)
и внутри обработчика:
if(night_callbacks == len(registration.live_players)):
apscheduler.reschedule_job(job_id = job.id, trigger = 'date', run_date = datetime.now())