Асинхронные методы

Slim.js — это легковесная библиотека для создания компонентной архитектуры в JavaScript. Одной из ключевых возможностей является использование асинхронных методов, которые позволяют обрабатывать данные, выполнять сетевые запросы и взаимодействовать с внешними API без блокировки основного потока выполнения.

Основы асинхронных методов

В Slim.js асинхронный метод объявляется с ключевым словом async и может использовать await для ожидания результатов промисов. Такие методы применяются как внутри компонентов, так и при их взаимодействии с внешними сервисами.

Пример объявления асинхронного метода в компоненте:

class MyComponent extends Slim {
    constructor() {
        super();
        this.data = null;
    }

    async fetchData(url) {
        try {
            const response = await fetch(url);
            this.data = await response.json();
            this.update(); // Обновление шаблона после изменения состояния
        } catch (error) {
            console.error('Ошибка загрузки данных:', error);
        }
    }
}

customElements.define('my-component', MyComponent);

Ключевые моменты:

  • Асинхронные методы позволяют работать с fetch, setTimeout и другими промис-ориентированными API.
  • После изменения состояния компонента необходимо вызывать this.update(), чтобы обновить DOM.

Интеграция асинхронных методов с жизненным циклом компонентов

Slim.js предоставляет несколько хуков жизненного цикла: onBeforeRender, onAfterRender, onBeforeUpdate и onAfterUpdate. Асинхронные методы можно безопасно вызывать внутри этих хуков для загрузки данных до или после рендеринга.

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

class UserList extends Slim {
    constructor() {
        super();
        this.users = [];
    }

    async onBeforeRender() {
        await this.loadUsers();
    }

    async loadUsers() {
        try {
            const response = await fetch('https://api.example.com/users');
            this.users = await response.json();
        } catch (error) {
            console.error(error);
        }
    }

    get template() {
        return `
            <ul>
                ${this.users.map(user => `<li>${user.name}</li>`).join('')}
            </ul>
        `;
    }
}

customElements.define('user-list', UserList);

Особенности:

  • Асинхронные операции могут завершаться после первого рендеринга, поэтому следует использовать this.update().
  • В onBeforeRender данные можно загружать заранее, чтобы рендер прошёл с уже готовой информацией.

Асинхронные события и методы взаимодействия

Компоненты Slim.js могут обрабатывать события, вызывая асинхронные методы в ответ на пользовательские действия, такие как клик или ввод текста.

class SearchComponent extends Slim {
    constructor() {
        super();
        this.results = [];
    }

    async onSearch(query) {
        try {
            const response = await fetch(`https://api.example.com/search?q=${query}`);
            this.results = await response.json();
            this.update();
        } catch (error) {
            console.error(error);
        }
    }

    get template() {
        return `
            <input type="text" onin put="this.parentNode.onSearch(this.value)">
            <ul>
                ${this.results.map(item => `<li>${item.title}</li>`).join('')}
            </ul>
        `;
    }
}

customElements.define('search-component', SearchComponent);

Важные моменты:

  • Асинхронные методы позволяют поддерживать реактивность данных без блокировки интерфейса.
  • Любое обновление состояния после асинхронной операции требует вызова this.update().

Обработка ошибок и отмена асинхронных операций

Асинхронные методы Slim.js могут сопровождаться средствами управления ошибками и отмены запросов. Для этого часто используют AbortController:

class DataFetcher extends Slim {
    constructor() {
        super();
        this.controller = null;
        this.data = [];
    }

    async fetchData(url) {
        if (this.controller) {
            this.controller.abort();
        }

        this.controller = new AbortController();
        try {
            const response = await fetch(url, { signal: this.controller.signal });
            this.data = await response.json();
            this.update();
        } catch (error) {
            if (error.name === 'AbortError') {
                console.log('Запрос отменён');
            } else {
                console.error('Ошибка при загрузке:', error);
            }
        }
    }
}

customElements.define('data-fetcher', DataFetcher);

Преимущества такого подхода:

  • Возможность отменять устаревшие или медленные запросы.
  • Улучшение производительности и предотвращение гонок данных.

Асинхронные методы и реактивные свойства

Slim.js позволяет связывать свойства компонента с шаблоном, а асинхронные методы могут изменять эти свойства. Любое изменение свойства автоматически вызывает ререндеринг, если используется this.update().

class ClockComponent extends Slim {
    constructor() {
        super();
        this.time = '';
    }

    async startClock() {
        while (true) {
            this.time = new Date().toLocaleTimeString();
            this.update();
            await new Promise(resolve => setTimeout(resolve, 1000));
        }
    }

    get template() {
        return `<p>Текущее время: ${this.time}</p>`;
    }
}

customElements.define('clock-component', ClockComponent);

Особенности:

  • Асинхронные циклы с await позволяют обновлять интерфейс без блокировки.
  • Свойства компонента могут быть реактивными и синхронно отображать новые данные после каждой асинхронной операции.

Использование асинхронных методов в комбинации с событиями жизненного цикла и шаблонами

Асинхронные методы могут сочетаться с другими возможностями Slim.js, создавая сложные, но управляемые интерфейсы:

  • Загрузка данных перед рендером (onBeforeRender)
  • Обновление шаблона после асинхронного действия (this.update())
  • Реакция на пользовательские события с асинхронной логикой
  • Отмена устаревших операций для оптимизации производительности

Эта комбинация позволяет строить динамичные компоненты, способные работать с сетевыми данными, таймерами и любыми промисами без заморочек с синхронизацией и ререндерингом.

Асинхронные методы в Slim.js — это инструмент, обеспечивающий плавность интерфейса, эффективное взаимодействие с внешними ресурсами и полную управляемость состояния компонента в реальном времени.