В SkateJS управление асинхронными операциями играет важную роль, особенно при работе с сетевыми запросами или таймерами внутри компонентов. Возможность отменять запросы позволяет предотвратить утечки памяти, исключить работу с устаревшими данными и повысить отзывчивость интерфейса.
Компоненты SkateJS основаны на классовой или функциональной модели,
где жизненный цикл строго регламентирован методами
connectedCallback, disconnectedCallback и
реактивными свойствами. Асинхронные операции, такие как
fetch, setTimeout или Promise,
должны быть безопасно завершены при удалении компонента из DOM.
Простейший подход — хранить ссылки на активные операции и очищать их
в disconnectedCallback:
import { define, Component, h } from 'skatejs';
class AsyncExample extends Component {
timeoutId;
connectedCallback() {
super.connectedCallback();
this.timeoutId = setTimeout(() => {
console.log('Асинхронная задача выполнена');
}, 5000);
}
disconnectedCallback() {
super.disconnectedCallback();
clearTimeout(this.timeoutId);
}
render() {
return <div>Асинхронный пример</div>;
}
}
define('async-example', AsyncExample);
В этом примере clearTimeout предотвращает выполнение
кода после удаления компонента, что обеспечивает корректное управление
жизненным циклом.
AbortControllerДля сетевых запросов используется стандартный API
AbortController. Этот механизм позволяет отменять
fetch при необходимости:
import { define, Component, h } from 'skatejs';
class FetchExample extends Component {
controller;
connectedCallback() {
super.connectedCallback();
this.controller = new AbortController();
fetch('https://api.example.com/data', { signal: this.controller.signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('Запрос был отменён');
} else {
console.error(err);
}
});
}
disconnectedCallback() {
super.disconnectedCallback();
this.controller.abort();
}
render() {
return <div>Пример fetch с отменой</div>;
}
}
define('fetch-example', FetchExample);
Ключевые моменты:
AbortController в
connectedCallback привязывает его к жизненному циклу
компонента.signal в fetch обеспечивает
возможность прерывания запроса.disconnectedCallback вызывается abort(),
что автоматически приводит к выбросу исключения AbortError
внутри промиса.Если компонент выполняет несколько параллельных запросов, следует использовать коллекцию контроллеров для управления ими:
import { define, Component, h } from 'skatejs';
class MultiFetchExample extends Component {
controllers = [];
connectedCallback() {
super.connectedCallback();
for (let i = 0; i < 3; i++) {
const controller = new AbortController();
this.controllers.push(controller);
fetch(`https://api.example.com/data/${i}`, { signal: controller.signal })
.then(res => res.json())
.then(data => console.log(`Данные ${i}:`, data))
.catch(err => {
if (err.name === 'AbortError') console.log(`Запрос ${i} отменён`);
});
}
}
disconnectedCallback() {
super.disconnectedCallback();
this.controllers.forEach(c => c.abort());
this.controllers = [];
}
render() {
return <div>Несколько fetch-запросов с отменой</div>;
}
}
define('multi-fetch-example', MultiFetchExample);
Такой подход гарантирует, что при удалении компонента будут прерваны все активные сетевые операции.
SkateJS поддерживает реактивные свойства через props.
Можно автоматически инициировать запрос при изменении свойства и
отменять предыдущий:
import { define, Component, h } from 'skatejs';
class ReactiveFetch extends Component {
static props = {
query: { attribute: true }
};
controller;
updated(prevProps) {
if (prevProps.query !== this.query) {
if (this.controller) this.controller.abort();
this.controller = new AbortController();
fetch(`https://api.example.com/search?q=${this.query}`, { signal: this.controller.signal })
.then(res => res.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') console.log('Предыдущий запрос отменён');
});
}
}
disconnectedCallback() {
super.disconnectedCallback();
if (this.controller) this.controller.abort();
}
render() {
return <div>Реактивный fetch: {this.query}</div>;
}
}
define('reactive-fetch', ReactiveFetch);
Особенности реализации:
updated вызывается при изменении свойства
query.AbortController привязывается к каждому запросу,
обеспечивая точную отмену.disconnectedCallback для предотвращения утечек памяти.AbortController для всех сетевых запросов,
особенно при динамическом обновлении данных.Этот подход к отмене запросов обеспечивает стабильную работу компонентов SkateJS в сложных интерфейсах с динамическим контентом и большим количеством асинхронных операций.