С выходом платформы 8.3.18 в экосистему 1С пришел долгожданный механизм асинхронного программирования. Долгое время разработчики были вынуждены использовать так называемый "callback-стиль", создавая громоздкие цепочки процедур через объект ОписаниеОповещения. В этой статье мы подробно разберем, как перейти на современный синтаксис Асинх/Ждать, выясним реальные ограничения платформы и проанализируем, почему этот механизм называют "неполноценным", несмотря на его очевидные преимущества.
Основная цель внедрения async/await в 1С — упрощение структуры кода при работе с интерактивными действиями и длительными операциями на клиенте. Рассмотрим стандартную ситуацию: нам нужно задать вопрос пользователю и, в зависимости от ответа, выполнить действие. Раньше это требовало создания как минимум двух процедур: основной и процедуры-обработчика оповещения.
Теперь же мы можем писать код линейно. Однако важно понимать технические требования: для использования ключевых слов Асинх и Ждать необходимо выполнение двух условий:
Для того чтобы функция могла "засыпать", ожидая завершения асинхронной операции, её необходимо объявить с модификатором Асинх. Внутри такой функции мы можем использовать оператор Ждать перед вызовом методов, которые возвращают объект Обещание (Promise).
Рассмотрим пример того, как преобразуется код (в анализе сложной логики также может помочь AI-Анализатор 1С (на базе Gemini)). Раньше мы писали так:
Процедура ВыполнитьДействие()
Оповещение = Новый ОписаниеОповещения("ПослеВопроса", ЭтотОбъект);
ПоказатьВопрос(Оповещение, "Продолжить выполнение?", РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
Процедура ПослеВопроса(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
Сообщить("Пользователь согласился");
КонецЕсли;
КонецПроцедуры
Теперь проанализируем, как этот же функционал выглядит с использованием нового механизма:
&НаКлиенте
Асинх Процедура ВыполнитьДействиеАсинх()
Результат = Ждать ПоказатьВопросАсинх("Продолжить выполнение?", РежимДиалогаВопрос.ДаНет);
Если Результат = КодВозвратаДиалога.Да Тогда
Сообщить("Пользователь согласился");
КонецЕсли;
КонецПроцедуры
Как мы видим, код стал линейным, исчезла необходимость в экспортных процедурах-обработчиках и передаче контекста через ДополнительныеПараметры.
В сообществе разработчиков часто звучит мнение, что асинхронность в 1С реализована не полностью. Давайте разберем, почему это так, и какие существуют ограничения:
Ждать просто приостанавливает выполнение текущего метода, позволяя платформе обрабатывать другие интерфейсные события (например, перерисовку формы), пока ожидается ответ от системы или пользователя.Асинх и Ждать не существует. Это связано с архитектурой сервера 1С, который работает в синхронном блокирующем режиме.Ждать работает только с методами, возвращающими Обещание. Большинство старых методов (например, ПоказатьВопрос) не возвращают ничего, поэтому для них платформа выпустила дубликаты с постфиксом Асинх (например, ПоказатьВопросАсинх).ПередЗаписью) "ждать" завершения вашей асинхронной функции. Если вы вызовете асинхронный метод из ПередЗаписью, событие завершится раньше, чем придет ответ от асинхронного метода.Объект Обещание (Promise) является фундаментом новой технологии. Когда вызывается асинхронный метод (например, КопироватьФайлАсинх), он мгновенно возвращает Обещание. Это своего рода "квитанция", которая обещает, что результат будет предоставлен позже.
Если мы вызываем метод без Ждать, выполнение пойдет дальше:
// Файл начнет копироваться, но код не остановится
Обещание = КопироватьФайлАсинх(Путь1, Путь2);
Сообщить("Копирование запущено...");
Если же мы используем Ждать, платформа "замораживает" выполнение данной процедуры до тех пор, пока Обещание не будет исполнено.
Несмотря на ограничения, переход на Асинх/Ждать крайне рекомендован для новых разработок (изучите также Шаблоны для применения cтандартов и методик разработки конфигураций 1С) по следующим причинам:
Попытка...Исключение вокруг асинхронного вызова. В старом стиле обработки ошибок внутри callback-процедур были крайне запутанными, и разработчикам часто требовался Помощник отладки (мини Vanessa).Ждать. Нам больше не нужно упаковывать данные в структуру ДополнительныеПараметры, чтобы протащить их в процедуру оповещения.Представим ситуацию: нам нужно проверить наличие файла, если его нет — спросить пользователя о создании, и если он согласен — создать файл и открыть его. Посмотрим, насколько лаконично это выглядит в асинхронном исполнении:
&НаКлиенте
Асинх Процедура РаботаСФайломАсинх()
Путь = "C:\temp\data.txt";
Файл = Новый Файл(Путь);
Существует = Ждать Файл.СуществуетАсинх();
Если Не Существует Тогда
Ответ = Ждать ПоказатьВопросАсинх("Файл не найден. Создать?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
Попытка
// Предположим, есть метод создания
Ждать СоздатьКаталогАсинх("C:\temp");
Сообщить("Файл успешно создан (имитация)");
Исключение
Сообщить("Ошибка при работе: " + КраткоеОписаниеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Механизм async/await в 1С — это мощный инструмент для избавления от "callback hell". Хотя он не приносит честной многопоточности и ограничен клиентской частью, его использование делает код чище, надежнее и проще в поддержке. Если ваша платформа и режим совместимости позволяют — смело отказывайтесь от ОписаниеОповещения в пользу Асинх-методов.