Haunted — это современная библиотека для создания веб-компонентов с
использованием реактивного подхода на базе хуков, похожих на React.
Одной из ключевых задач при работе с компонентами является корректная
обработка асинхронных данных, например промисов. Хук until
решает эту задачу, позволяя отложенно рендерить результат промиса,
одновременно предоставляя возможность отображения промежуточного
состояния.
untilХук until используется для рендеринга содержимого на
основе промиса. Он принимает два аргумента:
Синтаксис:
import { html, until } from 'haunted';
const Component = () => {
const dataPromise = fetch('/api/data').then(res => res.json());
return html`
<div>
${until(dataPromise.then(data => html`<p>${data.message}</p>`), html`<p>Загрузка...</p>`)}
</div>
`;
};
В этом примере до получения ответа от API отображается текст
Загрузка.... Как только промис завершится, содержимое
заменяется на результат запроса.
until особенно полезен при работе с компонентами, где
асинхронные данные могут находиться в нескольких состояниях: загрузка,
успех, ошибка. Для обработки ошибок промиса можно использовать метод
catch:
const dataPromise = fetch('/api/data')
.then(res => res.json())
.catch(err => html`<p>Ошибка загрузки данных: ${err.message}</p>`);
return html`
${until(dataPromise, html`<p>Загрузка данных...</p>`)}
`;
В этом подходе фоллбэк показывается до получения результата, а в случае ошибки рендерится альтернативное сообщение.
Haunted позволяет создавать реактивные состояния с помощью
useState и других хуков. until можно
комбинировать с useState для динамического обновления
данных:
import { useState } from 'haunted';
const AsyncComponent = () => {
const [url, setUrl] = useState('/api/data');
const dataPromise = fetch(url).then(res => res.json());
return html`
<div>
${until(
dataPromise.then(data => html`<p>${data.message}</p>`),
html`<p>Загрузка...</p>`
)}
<button @click=${() => setUrl('/api/other')}>Загрузить другие данные</button>
</div>
`;
};
При смене URL автоматически перерендеривается содержимое компонента после завершения нового промиса.
until может обрабатывать один промис, но для работы с
несколькими асинхронными источниками часто используют
Promise.all:
const data1 = fetch('/api/data1').then(res => res.json());
const data2 = fetch('/api/data2').then(res => res.json());
return html`
${until(
Promise.all([data1, data2]).then(([d1, d2]) => html`
<p>Первый источник: ${d1.message}</p>
<p>Второй источник: ${d2.message}</p>
`),
html`<p>Загрузка нескольких источников...</p>`
)}
`;
Такой подход позволяет рендерить только тогда, когда все промисы завершены, сохраняя чистоту кода и предотвращая множественные промежуточные состояния.
until подходит не только для данных, но и для
динамического импорта модулей:
const LazyComponent = () => html`
${until(
import('./heavy-component.js').then(module => module.default()),
html`<p>Компонент загружается...</p>`
)}
`;
Это позволяет оптимизировать производительность, загружая тяжёлые компоненты только при необходимости, а пользователю показывать промежуточное состояние.
until не блокирует рендеринг:
компонент отображает фоллбэк сразу, промис завершится асинхронно.then/catch для предотвращения сбоев
рендеринга.until превращает работу с промисами в Haunted в
предсказуемый и удобный процесс, обеспечивая плавный переход между
состояниями загрузки, успешного получения данных и ошибок без громоздких
конструкций.