SkateJS — это современная библиотека для создания веб-компонентов на базе Web Components и реактивных паттернов. Одной из критически важных задач при работе с компонентами, взаимодействующими с сетью, является обработка ошибок сетевых запросов. Неправильная обработка может привести к неконсистентному состоянию компонента, зависаниям интерфейса или некорректному отображению данных.
В SkateJS реактивные свойства объявляются через props
или хук useState. При работе с сетевыми запросами важно
разделять состояние запроса и состояние ошибки:
import { Component, h, prop } from 'skatejs';
class UserProfile extends Component {
static props = {
userId: prop.number,
userData: prop.object,
error: prop.string
};
connectedCallback() {
super.connectedCallback();
this.fetchUserData();
}
async fetchUserData() {
this.error = null; // Сброс ошибки перед запросом
try {
const response = await fetch(`https://api.example.com/users/${this.userId}`);
if (!response.ok) {
throw new Error(`Ошибка сети: ${response.status}`);
}
this.userData = await response.json();
} catch (err) {
this.error = err.message;
}
}
render() {
if (this.error) {
return <div class="error">{this.error}</div>;
}
if (!this.userData) {
return <div>Загрузка...</div>;
}
return <div>{this.userData.name}</div>;
}
}
customElements.define('user-profile', UserProfile);
Ключевые моменты:
error используется для хранения информации о
сетевой ошибке.try...catch гарантирует перехват как
сетевых ошибок (fetch), так и ошибок обработки ответа
(response.json()).error перед новым запросом предотвращает
отображение устаревших сообщений.Для повышения устойчивости приложения полезно реализовать механизм повторных попыток (retry):
async fetchWithRetry(url, retries = 3, delay = 1000) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`Ошибка: ${response.status}`);
return await response.json();
} catch (err) {
if (i === retries - 1) throw err;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
retries определяет количество повторных попыток.delay задает паузу между попытками.SkateJS-компонент может использовать этот метод так же, как обычный
fetch, сохраняя реактивное обновление состояния:
this.userData = await this.fetchWithRetry(`https://api.example.com/users/${this.userId}`);
Эффективная обработка ошибок сети включает наглядное отображение состояния ошибки пользователю:
render() {
if (this.error) {
return (
<div class="error">
{this.error}
<button onCl ick={() => this.fetchUserData()}>Попробовать снова</button>
</div>
);
}
if (!this.userData) {
return <div>Загрузка...</div>;
}
return <div>{this.userData.name}</div>;
}
При изменении свойств компонента или быстром размонтировании важно отменять устаревшие сетевые запросы, чтобы избежать состояния гонки:
connectedCallback() {
super.connectedCallback();
this.controller = new AbortController();
this.fetchUserData();
}
disconnectedCallback() {
super.disconnectedCallback();
if (this.controller) {
this.controller.abort();
}
}
async fetchUserData() {
this.error = null;
try {
const response = await fetch(
`https://api.example.com/users/${this.userId}`,
{ signal: this.controller.signal }
);
if (!response.ok) throw new Error(`Ошибка сети: ${response.status}`);
this.userData = await response.json();
} catch (err) {
if (err.name !== 'AbortError') {
this.error = err.message;
}
}
}
AbortController для контроля жизненного
цикла запроса.AbortError),
игнорируются.Ошибки сети могут быть разного типа:
HTTP ошибки (4xx, 5xx)
Сетевые сбои (timeout, offline)
navigator.onLine и обработку
TypeError при fetch.Ошибки данных (невалидный JSON)
try...catch для
response.json()loading, error и data отдельно
для чистой логики рендера.prop автоматически перерисовывают компонент, что
исключает ручное управление DOM.Обработка ошибок сети в SkateJS требует комбинации реактивного управления состоянием, асинхронных операций и контроля жизненного цикла компонентов. Следуя описанным подходам, компоненты становятся устойчивыми, предсказуемыми и безопасными в работе с нестабильными сетевыми условиями.