Как использовать async/await в 1С:Предприятие 8.3 и заменить ОписаниеОповещения

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

С выходом платформы 8.3.18 в экосистему 1С пришел долгожданный механизм асинхронного программирования. Долгое время разработчики были вынуждены использовать так называемый "callback-стиль", создавая громоздкие цепочки процедур через объект ОписаниеОповещения. В этой статье мы подробно разберем, как перейти на современный синтаксис Асинх/Ждать, выясним реальные ограничения платформы и проанализируем, почему этот механизм называют "неполноценным", несмотря на его очевидные преимущества.

Разберем основы: что изменилось в платформе

Основная цель внедрения async/await в 1С — упрощение структуры кода при работе с интерактивными действиями и длительными операциями на клиенте. Рассмотрим стандартную ситуацию: нам нужно задать вопрос пользователю и, в зависимости от ответа, выполнить действие. Раньше это требовало создания как минимум двух процедур: основной и процедуры-обработчика оповещения.

Теперь же мы можем писать код линейно. Однако важно понимать технические требования: для использования ключевых слов Асинх и Ждать необходимо выполнение двух условий:

  1. Версия платформы должна быть не ниже 8.3.18.
  2. Режим совместимости конфигурации должен быть установлен в значение "8.3.18" или выше. Если платформа актуальная, а режим совместимости старый (например, 8.3.14), конфигуратор выдаст синтаксическую ошибку, которую поможет найти Анализ конфигураций, расширений, отчетов и обработок на наличие ошибок (версия 5). Анализ состава расширений..

Проанализируем синтаксис: Асинх и Ждать

Для того чтобы функция могла "засыпать", ожидая завершения асинхронной операции, её необходимо объявить с модификатором Асинх. Внутри такой функции мы можем использовать оператор Ждать перед вызовом методов, которые возвращают объект Обещание (Promise).

Рассмотрим пример того, как преобразуется код (в анализе сложной логики также может помочь AI-Анализатор 1С (на базе Gemini)). Раньше мы писали так:


Процедура ВыполнитьДействие()
    Оповещение = Новый ОписаниеОповещения("ПослеВопроса", ЭтотОбъект);
    ПоказатьВопрос(Оповещение, "Продолжить выполнение?", РежимДиалогаВопрос.ДаНет);
КонецПроцедуры

Процедура ПослеВопроса(Результат, ДополнительныеПараметры) Экспорт
    Если Результат = КодВозвратаДиалога.Да Тогда
        Сообщить("Пользователь согласился");
    КонецЕсли;
КонецПроцедуры

Теперь проанализируем, как этот же функционал выглядит с использованием нового механизма:


&НаКлиенте
Асинх Процедура ВыполнитьДействиеАсинх()
    Результат = Ждать ПоказатьВопросАсинх("Продолжить выполнение?", РежимДиалогаВопрос.ДаНет);
    
    Если Результат = КодВозвратаДиалога.Да Тогда
        Сообщить("Пользователь согласился");
    КонецЕсли;
КонецПроцедуры

Как мы видим, код стал линейным, исчезла необходимость в экспортных процедурах-обработчиках и передаче контекста через ДополнительныеПараметры.

Выясним причины "неполноценности" механизма

В сообществе разработчиков часто звучит мнение, что асинхронность в 1С реализована не полностью. Давайте разберем, почему это так, и какие существуют ограничения:

  1. Отсутствие параллелизма: Асинхронность в 1С — это не многопоточность. Код не выполняется параллельно в фоновом режиме. Оператор Ждать просто приостанавливает выполнение текущего метода, позволяя платформе обрабатывать другие интерфейсные события (например, перерисовку формы), пока ожидается ответ от системы или пользователя.
  2. Только клиентская часть: Механизм работает исключительно в тонком, толстом и веб-клиенте. На сервере ключевых слов Асинх и Ждать не существует. Это связано с архитектурой сервера 1С, который работает в синхронном блокирующем режиме.
  3. Ограниченный набор методов: Вы не можете сделать любую произвольную функцию "ожидаемой". Оператор Ждать работает только с методами, возвращающими Обещание. Большинство старых методов (например, ПоказатьВопрос) не возвращают ничего, поэтому для них платформа выпустила дубликаты с постфиксом Асинх (например, ПоказатьВопросАсинх).
  4. Проблема обработчиков событий: Это наиболее критичное ограничение. Вы не можете заставить стандартное событие платформы (например, ПередЗаписью) "ждать" завершения вашей асинхронной функции. Если вы вызовете асинхронный метод из ПередЗаписью, событие завершится раньше, чем придет ответ от асинхронного метода.

Рассмотрим подробнее работу с объектом Обещание

Объект Обещание (Promise) является фундаментом новой технологии. Когда вызывается асинхронный метод (например, КопироватьФайлАсинх), он мгновенно возвращает Обещание. Это своего рода "квитанция", которая обещает, что результат будет предоставлен позже.

Если мы вызываем метод без Ждать, выполнение пойдет дальше:


// Файл начнет копироваться, но код не остановится
Обещание = КопироватьФайлАсинх(Путь1, Путь2);
Сообщить("Копирование запущено..."); 

Если же мы используем Ждать, платформа "замораживает" выполнение данной процедуры до тех пор, пока Обещание не будет исполнено.

Разберем преимущества использования нового синтаксиса

Несмотря на ограничения, переход на Асинх/Ждать крайне рекомендован для новых разработок (изучите также Шаблоны для применения cтандартов и методик разработки конфигураций 1С) по следующим причинам:

Посмотрим на пример сложной логики

Представим ситуацию: нам нужно проверить наличие файла, если его нет — спросить пользователя о создании, и если он согласен — создать файл и открыть его. Посмотрим, насколько лаконично это выглядит в асинхронном исполнении:


&НаКлиенте
Асинх Процедура РаботаСФайломАсинх()
    Путь = "C:\temp\data.txt";
    Файл = Новый Файл(Путь);
    
    Существует = Ждать Файл.СуществуетАсинх();
    
    Если Не Существует Тогда
        Ответ = Ждать ПоказатьВопросАсинх("Файл не найден. Создать?", РежимДиалогаВопрос.ДаНет);
        Если Ответ = КодВозвратаДиалога.Да Тогда
            Попытка
                // Предположим, есть метод создания
                Ждать СоздатьКаталогАсинх("C:\temp");
                Сообщить("Файл успешно создан (имитация)");
            Исключение
                Сообщить("Ошибка при работе: " + КраткоеОписаниеОшибки(ИнформацияОбОшибке()));
            КонецПопытки;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Вывод

Механизм async/await в 1С — это мощный инструмент для избавления от "callback hell". Хотя он не приносит честной многопоточности и ограничен клиентской частью, его использование делает код чище, надежнее и проще в поддержке. Если ваша платформа и режим совместимости позволяют — смело отказывайтесь от ОписаниеОповещения в пользу Асинх-методов.

← На главную