...

4.2. Async/await

Тема в разделе "Руководство по настройке форм и сценариев", создана пользователем ELMA365, 16 авг 2023.

  1. ELMA365

    ELMA365 Moderator

    Перед тем как смотреть пример из этого раздела рекомендуем изучить информацию в TS SDK про асинхронное выполнение (async/await).

    Для начала добавим в наш виджет days_count асинхронные операции. Для расчёта рабочих часов будем использовать методы рабочего календаря:
    Код:
    
    async function onInit(): Promise<void> {
        if (!
    Context.data.first_date) {
            return;
        }
        if (!
    Context.data.second_date) {
            return;
        }
        
    // Вычисляем календарные дни
        
    const duration Context.data.first_date.sub(Context.data.second_date);
        if (
    duration) {
            
    Context.data.days_count Math.round(Math.abs(duration.days));
        }
        
    // Вычисляем рабочие часы
        
    try {
            
    // Обращаемся к рабочему календарю
            
    const workTime await System.productionSchedule.getWorkingTime(Context.data.first_dateContext.data.second_date);
            
    Context.data.hours_count workTime.hours;
        }
        catch (
    err) {
            
    // Здесь нужно обработать ошибку
        
    }
    }
    Также доработаем отображение. Сделаем так, чтобы панели с продолжительностью отпуска и пересечениями показывались, только когда пользователь заполняет хотя бы одну дату на форме:
    Код:
    
    <%if (Context.data.days_count || Context.data.hours_count) { %>
      <
    div class="days_count">
        <
    div>
          <%= 
    Context.data.first_date.format("DD.MM.YYYY") %> - <%= Context.data.second_date.format("DD.MM.YYYY")%>
          (<%= 
    Context.data.days_count%> дней, <%= Context.data.hours_count%> раб.часов)
        </
    div>
      </
    div>
    <% } %>
    Теперь в виджете учитываются выходные и праздничные дни, однако для этого отправляется запрос на сервер.

    Форма с виджетом будет выглядеть следующим образом:

    [​IMG]

    Попробуем ускорить отображение виджета. Для этого вынесем получение рабочих часов в отдельную функцию и будем вызывать её без await:
    Код:
    
    async function onInit(): Promise<void> {
        if (!
    Context.data.first_date) {
            return;
        }
        if (!
    Context.data.second_date) {
            return;
        }
        
    // Вычисляем календарные дни
        
    const duration Context.data.first_date.sub(Context.data.second_date);
        if (
    duration) {
            
    Context.data.days_count Math.round(Math.abs(duration.days));
        }
        
    calcWorkHours();
    }
    async function calcWorkHours(): Promise<void> {
        
    // Вычисляем рабочие часы
        
    try {
            
    // Обращаемся к рабочему календарю
            
    const workTime await System.productionSchedule.getWorkingTime(Context.data.first_date!, Context.data.second_date!);
            
    Context.data.hours_count workTime.hours;
        }
        catch (
    err) {
            
    // Здесь нужно обработать ошибку
        
    }
    }
    В данном виджете различие в скорости почти незаметно. Попробуем сделать такую же операцию со вторым виджетом, vacation_overlap:
    Код:
    
    async function onInit(): Promise<void> {
        if (!
    Context.data.first_date || !Context.data.second_date) {
            return;
        }
        
    Server.rpc.getVacationOverlap();
    }
    На форме создания отпуска будет заметно, что сначала отобразится пустая панель Пересечения:

    [​IMG]

    И только через какое-то время отобразится список отпусков:

    [​IMG]

    Такой подход помогает выиграть время при открытии формы или виджета. Если загрузка данных занимает более 300 мс, выносите её в асинхронные функции и вызывайте без await.
    Последнее редактирование: 16 авг 2023
  2. fedorova

    fedorova Участник

  3. ava_var

    ava_var Активный участник

    1. Функция будет запущена, но программа не будет ждать ее завершения и пойдет дальше по коду.
    Например вызов функции записи в лог. Вызываем ее и не ждем - выполнится она или нет. Если упадет - на нашу программу это не повлияет, мы уже свою работу выполнили.

    2. Функция будет запущена и программа будет ждать результата выполнения.
    В данном случае мы будем ждать когда функция логирования сделает свою работу.

    3. По сути это эквивалентно первому варианту, т.к. async/await это удобная обертка над Promise