В современной разработке на платформе 1С:Предприятие часто возникает задача обеспечения отзывчивости интерфейса при выполнении длительных операций. Типичный пример: при поступлении звонка в колл-центр необходимо мгновенно запросить данные из внешней CRM или веб-сервиса, не «замораживая» при этом работу менеджера. В этой статье мы разберем, как уйти от классического последовательного выполнения кода к реактивному стилю и реализовать подобие callback-механизма.
Проанализируем самый распространенный метод, который часто называют «опросом» (polling). Несмотря на то, что он не является истинно реактивным, это штатный механизм, не требующий дополнительных лицензий или внешних модулей.
Суть метода заключается в разделении задачи на два потока. Основной сеанс пользователя инициирует фоновое задание, которое выполняется на сервере параллельно. Основной поток при этом остается свободным для работы пользователя. Разберем по шагам, как это реализовать:
ФоновыеЗадания.Выполнить().Пример кода для запуска такого процесса:
// На клиенте
Процедура ЗапуститьПолучениеДанных()
ПараметрыЗадания = Новый Структура("НомерТелефона", ТекущийНомер);
РезультатЗапуска = НачатьВыполнениеНаСервере(ПараметрыЗадания);
ИдентификаторЗадания = РезультатЗапуска.Идентификатор;
// Подключаем опрос результата
ПодключитьОбработчикОжидания("ПроверитьЗавершениеЗадания", 1, Ложь);
КонецПроцедуры
Процедура ПроверитьЗавершениеЗадания()
Если ЗаданиеЗавершено(ИдентификаторЗадания) Тогда
ОтключитьОбработчикОжидания("ПроверитьЗавершениеЗадания");
ОбработатьРезультат();
КонецЕсли;
КонецПроцедуры
Главный недостаток этого метода — лишняя нагрузка на сервер из-за постоянных вызовов и задержка между фактическим завершением задачи и моментом, когда 1С «узнает» об этом.
Рассмотрим более продвинутый и современный способ, который максимально приближен к реактивной модели. Система взаимодействия в 1С позволяет отправлять push-уведомления непосредственно в сеанс пользователя.
В этом сценарии фоновое задание после получения данных от внешнего сервиса не просто записывает их в базу, а отправляет сообщение через механизм Системы взаимодействия. Основной сеанс пользователя «подписывается» на получение сообщений. Как только сообщение приходит, срабатывает обработчик оповещения — это и есть наш искомый callback.
Для реализации этого метода нам потребуются следующие объекты:
МенеджерСистемыВзаимодействия для отправки сообщений.УстановитьОбработчикОповещенияОНовыхСообщениях на стороне клиента.Этот подход избавляет от необходимости постоянного опроса базы данных. Система сама «толкнет» клиентское приложение, когда данные будут готовы. Это позволяет добиться практически мгновенной реакции интерфейса на внешние события.
Выясним причину, по которой профессиональные разработчики часто выбирают внешние компоненты (ВК) для задач колл-центров. Когда требуется интеграция с оборудованием или специфическими протоколами (TCP, WebSockets), встроенных средств 1С может быть недостаточно.
Внешняя компонента, написанная на C++ или C#, может порождать собственные потоки выполнения внутри операционной системы. Когда поток завершает работу, компонента генерирует Внешнее событие. В 1С это событие перехватывается в стандартной процедуре ОбработкаВнешнегоСобытия.
Преимущества данного метода:
Рассмотрим пример обработки события в модуле формы или управляемого приложения:
Процедура ПриОткрытии()
// Загрузка и инициализация компоненты
ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаТелефонии", "SoftPhone", ТипВнешнейКомпоненты.Native);
ОбъектВК = Новый ("AddIn.SoftPhone.Extension");
КонецПроцедуры
Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
Если Источник = "SoftPhone" И Событие = "IncomingCallData" Тогда
// Это и есть наш callback!
ОбновитьДанныеКлиентаНаФорме(Данные);
КонецЕсли;
КонецПроцедуры
Проанализируем нестандартный, но эффективный метод использования JavaScript внутри 1С. Поле HTML-документа — это полноценный браузерный движок внутри формы. Мы можем загрузить в него скрипт, который будет выполнять асинхронные HTTP-запросы (AJAX или Fetch API).
Разберем алгоритм работы:
ПолеHTMLДокумента.Документ.parentWindow.eval() или запись в Текст запускается JavaScript-код, инициирующий запрос к внешнему сервису.window.external.MessageTo1C() (в зависимости от версии платформы и режима работы).Этот способ удобен тем, что позволяет использовать всю мощь веб-технологий (например, WebSockets) для получения данных в реальном времени без необходимости разработки полноценной внешней компоненты.
Существует также экзотический, но рабочий способ для Windows-систем — использование WMI (Windows Management Instrumentation). Можно настроить мониторинг создания определенного файла на диске. Внешний процесс (скрипт на Python, PowerShell или небольшая утилита) выполняет тяжелую работу и в финале создает файл с результатом. 1С, через подписку на события WMI, мгновенно получает уведомление о создании файла.
Однако, как отмечают эксперты, этот метод сложнее в поддержке и сильно зависит от прав доступа в операционной системе, поэтому его стоит рассматривать только в исключительных случаях.
Подводя итог нашему анализу, можно утверждать: решить задачу в реактивном стиле в 1С можно. Выбор конкретного инструмента зависит от масштаба задачи:
Помните, что главной целью является сохранение отзывчивости интерфейса для пользователя. Использование любого из вышеперечисленных методов вместо синхронного ожидания значительно повысит качество вашего программного продукта.