Перейти к содержанию

BSL154 — После вызова асинхронного метода есть строки кода

Кратко

После вызова асинхронного метода есть строки кода

Идентификаторы

Поле Значение
Код правила BSL154
Совместимый псевдоним CodeAfterAsyncCall
Серьёзность WARNING
Включено по умолчанию Да
Реализовано Да
Теги async, correctness

Поведение

  • Публичный идентификатор BSL154 и псевдоним CodeAfterAsyncCall стабильны.
  • Правило сообщает о случаях, описанных на этой странице.
  • Подавления и проектная конфигурация применяются до публикации результата.
  • Для выполнения правила не требуется внешний анализатор или сетевой доступ.

Настройка и подавление

Код BSL### — основной стабильный идентификатор. Совместимый псевдоним принимается в select, ignore и совместимых блоковых комментариях.

[tool.onec-hbk-bsl]
select = ["BSL154"]
ignore = ["CodeAfterAsyncCall"]

Все три семейства подавлений работают для текущей строки и диапазона. Если открывающий комментарий стоит после кода, он действует только на эту строку. Используйте любой один вариант:

  • noqa:
Значение = "пример";  // noqa: BSL154
  • bsl-disable (совместимый вариант):
Значение = "пример";  // bsl-disable: BSL154
  • совместимый BSLLS-вариант:
Значение = "пример";  // BSLLS:CodeAfterAsyncCall-off

Если тот же открывающий комментарий стоит на отдельной строке, он начинает диапазон. Закройте его парным маркером того же семейства:

// noqa: BSL154
// код без этой диагностики
// noqa-enable: BSL154

// bsl-disable: BSL154
// код без этой диагностики
// bsl-enable: BSL154

// BSLLS:CodeAfterAsyncCall-off
// код без этой диагностики
// BSLLS:CodeAfterAsyncCall-on

Чтобы отключить правило до конца файла, не добавляйте закрывающий noqa-enable, bsl-enable или BSLLS:…-on.

Открывающий и закрывающий маркеры должны принадлежать одному семейству.

Описание диагностики

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

Для правильного решения нужно вынести весь код, который должен быть выполнен после выполнения асинхронного действия, в экспортный метод и указать его имя в обработке оповещения, которая будет вызвана после завершения асинхронного действия. Или использовать асинхронность через обещания, например, Ждать ПредупреждениеАсинх(Текст);

Примеры

Неверный код

&НаКлиенте
Процедура Команда1(Команда)
    ДополнительныеПараметры = Новый Структура("Результат", 10);
    Оповещение = Новый ОписаниеОповещения("ПослеВводаКоличества", ЭтотОбъект);
    ПоказатьВводЧисла(Оповещение, 1, "Введите количество", ДополнительныеПараметры.Результат, 2);

    Сообщить("Введенное количество равно " + ДополнительныеПараметры.Результат); // неверно, т.к. всегда будет 10
КонецПроцедуры

&НаКлиенте
Процедура ПослеВводаКоличества(Число, ДополнительныеПараметры) Экспорт
    Если Число <> Неопределено Тогда
         ДополнительныеПараметры.Результат = Число;
    КонецЕсли;
КонецПроцедуры;

Правильный код

&НаКлиенте
Процедура Команда1(Команда)
    ДополнительныеПараметры = Новый Структура("Результат", 10);
    Оповещение = Новый ОписаниеОповещения("ПослеВводаКоличества", ЭтотОбъект);
    ПоказатьВводЧисла(Оповещение, 1, "Введите количество", ДополнительныеПараметры.Результат, 2);

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

&НаКлиенте
Процедура ПослеВводаКоличества(Число, ДополнительныеПараметры) Экспорт
    Если Число <> Неопределено Тогда
        ДополнительныеПараметры.Результат = Число;
        Сообщить("Введенное количество равно " + ДополнительныеПараметры.Результат); // неверно, т.к. всегда будет 10
    КонецЕсли;
КонецПроцедуры;

В некоторых случаях выполнение кода сразу после вызова асинхронного метода вполне возможно, если не нужно ожидать результатов выполнения асинхронного действия. Например

&НаКлиенте
Процедура Команда1(Команда)
    ПоказатьПредупреждение(, "Предупреждаю", 10);
    Сообщить("начал работать код после ПоказатьПредупреждение");
    // ...
КонецПроцедуры

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

&НаКлиенте
Процедура Команда1(Команда)
    ДополнительныеПараметры = Новый Структура("Результат", 10);
    Если Условие Тогда
        Оповещение = Новый ОписаниеОповещения("ПослеВводаКоличества", ЭтотОбъект);
        ПоказатьВводЧисла(Оповещение, 1, "Введите количество", ДополнительныеПараметры.Результат, 2);
    Иначе
        // какой-то код
    КонецЕсли;
    // последующий код также может вызываться сразу после вызова асинхронного метода, что может быть неверно

    Сообщить("Введенное количество равно " + ДополнительныеПараметры.Результат); // неверно, т.к. всегда будет 10
КонецПроцедуры

Источники