на форме фильтр + грид
данные с бэка забираю через fetch
полученными данными обновляется грид
запрос довольно тяжелый / долгий
проблема возникает когда пользователь генерит новый запрос до завершения предыдущего
контент в гриде обновляется несколько раз
можно как то прервать / отказаться от "устаревшего" запроса?
P.S.
обертывание fetch в clearTimeout / setTimeout в данной ситуации не спасает
P.S.S.
или както проверять является ли полученный данные результатом последнего promis'а?
UPDATE
страница на ReactJS
публикация кода ничего не даст, т.к. проблема общего плана
ситуация в том, что нет кнопки "НАЙТИ", запрос генерится при каждом "чихе" в фильтре
фильтр огромный из 10ков полей и выпадающих списков
дисейблить его при каждом запросе не получится по идеалогическим соображениям клиента
вижу единственный вариант это отказываться или игнорировать устаревшие запросы
но хотел поискать BEST PRACTICES
UPDATE2
class View extends Component {
...
updateItems(data) {
self.state.timeoutItems && clearTimeout(self.state.timeoutItems);
self.state.timeoutItems = setTimeout(() => {
self.props.onGetItems(self.calcParams());
}, config.timeoutItems );
}
}
export default connect(
state => ({
items: state.items
}),
dispatch => ({
onGetItems: (o) => {
dispatch(getItems(o));
}
})
)(View);
...
export const getItems = (o = {}) => dispatch => {
...
fetch(url, {
method: 'GET',
headers: {
"Content-type": "application/json",
"Accept": "application/json"
},
})
.then( (response) => response.json() )
.then((data) => {
==>> (1) <<==
dispatch({ type: 'FETCH_ITEMS_SUCCESS', data: data });
})
.catch((error) => {
console.log('Request failed', error);
});
}
можно ли в точке (1) определить к какому promise относится полученный результат?
Ответ
На текущее время нативно отменить fetch нельзя, это потому что он использует механизм Promise-ов, в которых тоже нет механизма прерывания. Поэтому приходится ухитряться и писать костыли
Есть библиотека axios, тоже использует Promise, правда работает вроде все еще на стандартном XMLHttpRequest, но возможность отмены там есть
var CancelToken = axios.CancelToken;
var source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// handle error
}
});
// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');
Если хотите использовать нативный fetch придется пока писать свою реализацию отмены запроса (да и то, это не будет настоящей отменой запроса, потому что ответ все равно придет, просто вы его проигнорируете)
UPD
Дискасс на эту тему
Комментариев нет:
Отправить комментарий