В библиотеке Quasar управление HTTP-запросами обычно осуществляется через встроенный или подключаемый HTTP-клиент, чаще всего axios. Одним из ключевых аспектов работы с асинхронными запросами является возможность их отмены. Это особенно важно при динамических интерфейсах, когда пользователь может быстро менять параметры запроса или покидать страницу до завершения загрузки данных.
Quasar сам по себе не содержит отдельного API для отмены запросов, поэтому применяется стандартный подход через axios CancelToken или современный AbortController.
CancelToken позволяет создавать токен отмены, который
передаётся в конфигурацию запроса. Пример:
import axios from 'axios';
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/api/data', {
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
})
.then(response => {
console.log('Данные получены', response.data);
})
.catch(error => {
if (axios.isCancel(error)) {
console.log('Запрос отменён', error.message);
} else {
console.error('Ошибка запроса', error);
}
});
// В какой-то момент можно вызвать отмену
cancel('Пользователь отменил запрос');
Ключевые моменты:
cancel хранит функцию для отмены
запроса.axios.isCancel(error) позволяет корректно
обрабатывать именно отмену, отличая её от обычных ошибок сети или
сервера.Современный подход через AbortController более универсален и поддерживается нативно в браузерах:
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.then(response => response.json())
.then(data => console.log('Данные', data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('Запрос был отменён');
} else {
console.error('Ошибка запроса', err);
}
});
// Отмена запроса
controller.abort();
Преимущества:
fetch без сторонних библиотек.В Quasar проекты обычно используют компоненты Vue. Отмена запросов становится критичной при навигации между страницами или динамическом обновлении данных.
Пример с onBeforeUnmount для автоматической отмены:
<template>
<q-btn label="Загрузить данные" @click="loadData" />
</template>
<script>
import { ref, onBeforeUnmount } from 'vue';
import axios from 'axios';
export default {
setup() {
const data = ref(null);
let cancel;
const loadData = () => {
if (cancel) cancel('Предыдущий запрос отменён');
const CancelToken = axios.CancelToken;
axios.get('/api/data', {
cancelToken: new CancelToken(c => (cancel = c))
})
.then(res => data.value = res.data)
.catch(err => {
if (axios.isCancel(err)) console.log(err.message);
else console.error(err);
});
};
onBeforeUnmount(() => {
if (cancel) cancel('Компонент размонтирован');
});
return { data, loadData };
}
};
</script>
Особенности интеграции:
Для сложных интерфейсов часто нужно отменять сразу несколько
запросов. С помощью AbortController это делается через
один контроллер, который передаётся в несколько fetch:
const controller = new AbortController();
Promise.all([
fetch('/api/data1', { signal: controller.signal }),
fetch('/api/data2', { signal: controller.signal }),
])
.then(responses => Promise.all(responses.map(r => r.json())))
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') console.log('Все запросы отменены');
});
controller.abort(); // Отмена сразу всех запросов
fetch, это современный и нативный подход.onBeforeUnmount) для предотвращения утечек памяти.Отмена запросов может быть связана с пользовательским интерфейсом:
import { Notify, Loading } from 'quasar';
const controller = new AbortController();
Loading.show();
fetch('/api/data', { signal: controller.signal })
.then(res => res.json())
.then(data => {
console.log(data);
Loading.hide();
})
.catch(err => {
Loading.hide();
if (err.name === 'AbortError') {
Notify.create({ message: 'Загрузка отменена', color: 'negative' });
} else {
Notify.create({ message: 'Ошибка запроса', color: 'negative' });
}
});
// При необходимости отмены
controller.abort();