Mithril.js предоставляет удобные механизмы для работы с асинхронными операциями, включая AJAX-запросы и промисы. Асинхронное программирование позволяет строить интерфейсы, которые не блокируют поток выполнения при ожидании ответа от сервера или другой медленной операции, обеспечивая отзывчивость приложения.
m.requestДля выполнения HTTP-запросов в Mithril используется функция
m.request. Она возвращает промис, который
можно использовать для обработки результата после завершения
запроса.
Пример простого GET-запроса:
m.request({
method: "GET",
url: "/api/data"
}).then(function(response) {
console.log(response);
}).catch(function(error) {
console.error(error);
});
Ключевые моменты:
m.request автоматически сериализует данные в JSON при
отправке и десериализует JSON-ответ сервера..then() и
.catch().Mithril-компоненты тесно интегрируются с промисами. Часто промисы используются для загрузки данных и последующего обновления модели компонента:
const MyComponent = {
data: null,
oninit: function() {
m.request({ method: "GET", url: "/api/users" })
.then(users => {
MyComponent.data = users;
})
.catch(err => console.error(err));
},
view: function() {
if (!MyComponent.data) return m("p", "Загрузка...");
return m("ul", MyComponent.data.map(user => m("li", user.name)));
}
};
Особенности:
m.request автоматически вызывает
m.redraw(), когда промис разрешается, что обеспечивает
обновление интерфейса без дополнительного кода.Промисы позволяют централизованно обрабатывать ошибки, возникающие при запросах или других асинхронных операциях:
m.request({ method: "POST", url: "/api/save", body: { name: "Alice" } })
.then(response => console.log("Успех:", response))
.catch(error => console.error("Ошибка:", error));
Для сложных сценариев возможна последовательная цепочка промисов:
m.request({ method: "GET", url: "/api/user" })
.then(user => m.request({ method: "GET", url: `/api/profile/${user.id}` }))
.then(profile => console.log("Профиль:", profile))
.catch(err => console.error(err));
async/awaitMithril полностью совместим с современными синтаксисами JavaScript,
включая async/await. Использование async/await
позволяет писать асинхронный код в синхронном стиле,
что повышает читаемость:
const MyAsyncComponent = {
data: null,
oninit: async function() {
try {
const response = await m.request({ method: "GET", url: "/api/items" });
MyAsyncComponent.data = response;
} catch (error) {
console.error(error);
}
},
view: function() {
if (!MyAsyncComponent.data) return m("p", "Загрузка...");
return m("ul", MyAsyncComponent.data.map(item => m("li", item.name)));
}
};
Преимущества использования
async/await:
.then().AbortControllerДля прерывания долгих или ненужных запросов можно использовать
AbortController, что особенно полезно при быстром переходе
между компонентами:
const controller = new AbortController();
m.request({
method: "GET",
url: "/api/data",
signal: controller.signal
}).then(data => console.log(data))
.catch(err => {
if (err.name === "AbortError") {
console.log("Запрос был отменен");
} else {
console.error(err);
}
});
// Отмена запроса
controller.abort();
m.redrawMithril автоматически инициирует перерисовку компонентов после
завершения промиса, возвращаемого m.request. При
использовании собственных промисов нужно вручную вызывать
m.redraw() для обновления интерфейса:
const fetchData = () => {
return new Promise(resolve => {
setTimeout(() => resolve("Данные получены"), 1000);
});
};
const AsyncComponent = {
data: null,
oninit: function() {
fetchData().then(result => {
AsyncComponent.data = result;
m.redraw();
});
},
view: function() {
return m("p", AsyncComponent.data || "Загрузка...");
}
};
Особенности работы:
m.request вызывает m.redraw()
автоматически.m.redraw() после изменения состояния.async/await повышает читаемость кода,
особенно при цепочках промисов.Асинхронное программирование в Mithril.js является ключевым инструментом для построения отзывчивых веб-приложений, обеспечивая плавную работу интерфейса при работе с сетевыми запросами и другими долгими операциями.