Как правильно вызывать асинхронные методы и получать результат их выполнения в 1С?

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

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

Понимаем суть асинхронности: разделение кода на «до» и «после»

Проанализируем ситуацию. В синхронном коде платформа приостанавливает выполнение текущей функции до тех пор, пока запрашиваемое действие не будет завершено. В асинхронной модели поток исполнения не останавливается: процедура инициирует операцию и моментально завершает свою работу.

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

  1. Подготовительная часть (ДО): инициализация асинхронной операции (например, открытие диалога выбора или запуск проверки файла).
  2. Завершающая часть (ПОСЛЕ): отдельная процедура-обработчик, которая вызывается платформой автоматически после завершения асинхронного процесса.

Классическое решение: использование объекта «ОписаниеОповещения»

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

Посмотрим на конкретный пример выбора файла и последующей проверки его существования с помощью асинхронных вызовов:


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

&НаКлиенте
Процедура ВыбратьФайлСертификатаЗавершение(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    
    Если ВыбранныеФайлы <> Неопределено Тогда
        ИмяФайла = ВыбранныеФайлы[0];
        ФайлОбъект = Новый Файл(ИмяФайла);
        
        // Передаем имя файла в контексте дополнительных параметров
        ОписаниеОповещенияПроверка = Новый ОписаниеОповещения("ПроверитьФайлЗавершение", ЭтаФорма, ИмяФайла);
        ФайлОбъект.НачатьПроверкуСуществования(ОписаниеОповещенияПроверка);
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьФайлЗавершение(ФайлСуществует, ИмяФайла) Экспорт
    
    Если ФайлСуществует Тогда
        // Продолжение работы: чтение и обработка файла
        ОбработатьФайл(ИмяФайла);
    Иначе
        ПоказатьПредупреждение(, "Указанный файл не найден на диске!");
    КонецЕсли;

КонецПроцедуры

Обратите внимание: процедуры-обработчики, указанные в ОписаниеОповещения, обязательно должны содержать директиву Экспорт, иначе платформа не сможет вызвать их из внешнего контекста.

Современное решение: конструкции «Асинх / Ждать» (Платформа 8.3.18 и выше)

Начиная с версии платформы 8.3.18, появился удобный механизм работы с асинхронным кодом. С помощью модификатора Асинх и ключевого слова Ждать можно писать асинхронный код визуально линейным образом, не разбивая его вручную на множество процедур с оповещениями.

Вместо метода НачатьПроверкуСуществования() используется асинхронный метод СуществуетАсинх(). Разберем по шагам, как это реализовать:


&НаКлиенте
Асинх Функция ФайлСуществуетАсинх(ПутьКФайлу)
    
    ФайлОбъект = Новый Файл(ПутьКФайлу);
    // Оператор Ждать приостанавливает выполнение метода до получения ответа
    Возврат Ждать ФайлОбъект.СуществуетАсинх();
    
КонецФункции

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

КонецПроцедуры

Ключевые правила и ограничения работы с асинхронным кодом

При проектировании алгоритмов с асинхронными вызовами следует учитывать важные особенности платформы:

  1. Область применения оператора Ждать: данный оператор разрешено использовать исключительно внутри процедур и функций, объявленных с модификатором Асинх. Использование его в обычном методе приведет к ошибке компиляции.
  2. Тип возвращаемого значения: любая Асинх Функция всегда возвращает объект типа Обещание. Для извлечения фактического значения из обещания вызывающий код обязан использовать оператор Ждать.
  3. Различие между процедурой и функцией: процедуру с ключевым словом Асинх нельзя приостановить снаружи с помощью Ждать, так как она не возвращает Обещание. Если необходимо гарантированно дождаться завершения всей цепочки действий, используйте Асинх Функция.
  4. Передача параметров: все параметры в асинхронных методах всегда передаются по значению (режим Знач), поэтому изменить значение переменной вызывающего контекста напрямую из асинхронной функции не получится.
  5. Запрет синхронных вызовов: в веб-клиенте и в тонком клиенте при строгом режиме запрета синхронных вызовов использование асинхронных методов (таких как СуществуетАсинх()) является строго обязательным требованием платформы.
← На главную