С переходом платформы 1С:Предприятие на асинхронную модель работы (отказ от модальности), многие разработчики столкнулись с ситуацией, когда код «проскакивает» выполнение интерактивных методов, таких как ВвестиСтрокуАсинх, ПоказатьВопросАсинх или ПоместитьФайлНаСерверАсинх. Особенно часто это проявляется при выносе бизнес-логики из модуля формы в общие модули. В этой статье мы подробно разберем, почему так происходит, как работает механизм Async/Await в 1С и как правильно выстраивать цепочки вызовов, чтобы программа работала предсказуемо.
Рассмотрим типичную ситуацию: разработчик вызывает асинхронный метод ввода строки. В модуле формы все работает корректно — выполнение процедуры приостанавливается до тех пор, пока пользователь не введет данные. Однако, как только этот же код переносится в Общий модуль, поведение меняется: система инициирует диалог ввода, но сразу же переходит к выполнению следующих строк кода, не дожидаясь ответа пользователя.
Проанализируем основную причину: асинхронность в 1С является «инфекционной». Если вы выносите асинхронную операцию в отдельную функцию, то вся иерархия вызовов выше тоже должна стать асинхронной и явно ожидать завершения вложенной операции. Обнаружить места, где нарушена логика вызовов, поможет статический анализатор кода проектов, который проверяет исходные тексты на соответствие стандартам.
Для глубокого понимания процесса нам необходимо выяснить, что именно происходит в момент вызова метода с суффиксом Асинх. Когда мы вызываем ВвестиСтрокуАсинх, система не возвращает строку немедленно. Она возвращает специальный объект типа Обещание. Это своего рода «квитанция», которая говорит: «Я закончу выполнение позже и тогда отдам результат».
Если мы не используем оператор Ждать, наша переменная просто получает этот объект-обещание, и код идет дальше. Оператор Ждать приостанавливает выполнение текущего метода до тех пор, пока Обещание не будет исполнено. При проектировании таких цепочек важно соблюдать единообразие кода.
Разберем по шагам, как должна выглядеть структура кода при взаимодействии формы и общего модуля.
Шаг 1. Подготовка общего модуля.
Во-первых, общий модуль должен быть клиентским. Во-вторых, функция должна быть помечена ключевым словом Асинх.
// Общий модуль: РаботаСДиалогамиКлиент
Асинх Функция ПолучитьТекстОтПользователяАсинх() Экспорт
Результат = "";
// Мы используем Ждать здесь, чтобы дождаться ответа системы
Подтверждение = Ждать ВвестиСтрокуАсинх(Результат, "Введите наименование");
Если Подтверждение Тогда
Сообщить("Пользователь ввел: " + Результат);
Возврат Результат;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Шаг 2. Вызов из модуля формы.
Здесь кроется самая частая ошибка. Даже если функция в общем модуле написана идеально, ее вызов в процедуре события также обязан содержать Ждать, а сама процедура должна быть помечена как Асинх.
// Модуль формы
&НаКлиенте
Асинх Процедура КомандаВыполнить(Команда)
// ПРАВИЛЬНО:
Результат = Ждать РаботаСДиалогамиКлиент.ПолучитьТекстОтПользователяАсинх();
Если Результат <> Неопределено Тогда
// Обработка полученных данных
ПродолжитьОбработкуНаСервере(Результат);
КонецЕсли;
КонецПроцедуры
Важно понимать, что Ждать в 1С не блокирует интерфейс полностью. Это реализация кооперативной многозадачности. Пока система ждет ввода от пользователя, она может выполнять другие задачи.
А вызывает функцию Б через Ждать, то функция А ОБЯЗАТЕЛЬНО должна быть Асинх.Обещание, если не использован оператор Ждать.Ждать процедура просто встанет в очередь событий и выполнится позже.Мы выяснили, что асинхронность в 1С требует дисциплины. Если вам кажется, что ВвестиСтрокуАсинх в общем модуле «пролетает» мимо, первым делом проверьте всю цепочку вызовов. Каждый уровень этой цепочки должен иметь пометку Асинх и вызывать нижестоящие уровни через Ждать. Только такая структура гарантирует, что бизнес-логика будет выполнена последовательно, а данные от пользователя будут получены вовремя.