Синхронную функцию из асинхронного кода обычно вызывают напрямую. Если результат должен участвовать в цепочке async/await, его при необходимости оборачивают в Promise.
Как вызвать синхронную функцию из асинхронного кода?
Синхронную функцию из асинхронного кода обычно вызывают напрямую. Если результат должен участвовать в цепочке async/await, его при необходимости оборачивают в Promise.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Как вызвать синхронную функцию из асинхронного кода?
- Асинхронный код выполняет операции без блокировки потока
- Синхронная функция завершается в текущем потоке и блокирует его на время работы
- Внутри async синхронную функцию можно вызвать напрямую — она всё равно выполнится синхронно в рамках async-контекста
- Если результат требуется представить как промис, его оборачивают в Promise.resolve() или используют async/await
- Так синхронную логику можно включить в асинхронный сценарий без специальной сложной обвязки
- В Node.js синхронные методы допустимо вызывать из async-кода, но на время выполнения они блокируют event loop
- Долгие синхронные операции снижают производительность и отзывчивость асинхронного приложения
Итого: Синхронную функцию из асинхронного кода обычно вызывают напрямую. Если результат должен участвовать в цепочке async/await, его при необходимости оборачивают в Promise.
Подробный ответ
Основной ответ
Вызвать синхронную функцию из асинхронного кода можно напрямую, но для длительных операций это опасно блокировкой event loop. Поэтому основной практический подход — перенести синхронную функцию в отдельный поток или процесс, оставив главный поток свободным. В Python для этого обычно применяют loop.run_in_executor(): функция выполняется в отдельном потоке или процессе, не останавливая асинхронный цикл.
Ключевые моменты
- Использование Executor: вызов
asyncio.get_event_loop().run_in_executor()запускает синхронный код параллельно и сохраняет отзывчивость async-программы. По умолчанию используетсяThreadPoolExecutor, однако для задач, чувствительных к GIL, можно выбратьProcessPoolExecutor. - Синтаксис с await: асинхронный вызов записывают как
await loop.run_in_executor(None, sync_func, *args). Это позволяет встроить синхронную функцию в async-поток без блокировки event loop. - Альтернативы: короткую функцию, которая практически не блокирует выполнение, можно вызвать непосредственно. Но более длительные операции создают задержки, а для тяжёлых вычислений предпочтительнее multiprocessing.
Практический контекст
В проектах на Python 3.7+ связка asyncio и run_in_executor считается стандартным способом подключать старые библиотеки и решения с синхронным интерфейсом, включая работу с файлами и сетевые вызовы в blocking mode. В React Native и Node.js используются сходные механизмы — worker threads или отдельные процессы. При правильной настройке это помогает сохранить высокий throughput и минимальную latency (~50ms или ниже).
Если потребуется, можно привести пример кода.