В качестве альтернативы отмене Axios вы можете использовать Обещание Bluebird Promise , что проще.
Преимущества новой отмены по сравнению со старой отменой:
- .cancel () является синхронным.
- код настройки не требуется для работы отмены
- сочетаются с другими функциями bluebird, такими как Promise.all
ЗдесьдемоЯ добавил некоторые записи в axios.get(...).then(...)
для отслеживания завершения каждого вызова.
Закомментируйте строку promises.forEach(p => p.cancel())
, чтобы убедиться, что без отмены безошибочные вызовы будут выполнены до завершения.
//for demo, check if fetch completes
const logCompleted = (res) => console.log(`Promise completed, '${res.config.url}'`)
function getChannels() {
return axios.get("https://reqres.in/api/users?page=1&delay=5").then(logCompleted)
}
function getContacts() {
return axios.get("https://reqres.in/api/users?page=2").then(logCompleted)
}
function getEventActions() {
return axios.get("https://httpbin.org/status/401").then(logCompleted)
}
Promise.config({ cancellation: true }); // Bluebird config
window.Promise = Promise; // axios promises are now Bluebird flavor
const promises = [getChannels(), getContacts(), getEventActions()];
Promise.all(promises)
.then(([channels, contacts, eventActions]) => {
console.log('Promise.all.then', { channels, contacts, eventActions });
})
.catch(err => {
console.log(`Promise.all.catch, '${err.message}'`)
promises.forEach(p => p.cancel());
})
.finally(() => console.log('Promise.all.finally'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/bluebird/latest/bluebird.core.min.js"></script>
Почему это работает
Promise.all () вместо axios.all ()
Глядя на эту старую проблему с axios Удалить axios.all
и axios.spread
# 1042 можно увидеть
Axios использует Promise.all под капотом ...
и этот
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// Both requests are now complete
}));
может быть заменен этим
Promise.all([getUserAccount(), getUserPermissions()])
.then(function ([acct, perms]) {
// Both requests are now complete
});
, поэтому мы можем перейти к работе с Promises напрямую и при этом иметь те же функции.
Обещания не выполняются быстро
С MDN мы видим
Promise.all отклоняется, если любой изэлементы отклонены.Например, если вы передаете четыре обещания, которые разрешаются после истечения времени ожидания, и одно обещание, которое сразу же отклоняется, то Promise.all будет отклонено немедленно.
, поэтому в этом шаблоне
Promise.all(...)
.then(...)
.catch(...);
.catch()
сработает, когда первое обещание не будет выполнено (в отличие от then()
, который ожидает завершения всех обещаний).
Составление Promise.all
и .cancel()
Шаблон довольно прост, просто отмените все обещания в .catch()
(который вызывается при первой ошибке).
Ссылка на этот вопрос для деталей Остановите другие обещания, когда Promise.all () отклоняет
Замена Bluebird в хранилище Vue
Это базовая реализация в Vuex.
yarn add bluebird
import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";
import Promise from 'bluebird';
Vue.use(Vuex);
Promise.config({ cancellation: true }); // Bluebird config
window.Promise = Promise; // axios promises are now Bluebird flavor
export default new Vuex.Store({
actions: {
fetchData({ dispatch }) {
function getChannels() {
return axios.get("https://reqres.in/api/users?page=1&delay=5");
}
function getContacts() {
return axios.get("https://reqres.in/api/users?page=2");
}
function getEventActions() { // 401 - auth error
return axios.get("https://httpbin.org/status/401");
}
const promises = [getChannels(), getContacts(), getEventActions()];
Promise.all(promises)
.then(([channels, contacts, eventActions]) => {
dispatch("channels/setChannels", channels.data, { root: true });
dispatch("contacts/setContacts", contacts.data, { root: true });
dispatch("events/setActions", eventActions.data, { root: true });
})
.catch(err => {
promises.forEach(p => p.cancel());
})
}
}
});