React componentDidMount async/await long polling
Есть сервер, который эмулириует long polling. Нужно слать запросы, пока не придет ответ типа {tickets: [], stop: true}.
Есть код:
async getTickets(prevToken) {
const token = prevToken ? prevToken : await this.getToken();
const response = await fetch(`https://front-test.beta.aviasales.ru/tickets?searchId=${token}`);
if (response.ok) {
let tickets = await response.json();
if (!tickets.stop) {
await this.getTickets(token);
} else {
return tickets.tickets;
// console.log(tickets.tickets);
}
} else if (response.status == '404') {
await this.getTickets()
} else {
await this.getTickets(token);
}
}
async componentDidMount() {
const tickets = await this.getTickets();
this.setState(state => ({
tickets: tickets
}))
}
в стейт возвращает undefined. Если же запускаю так, то возвращается правильный массив:
async getTickets(prevToken) {
const token = prevToken ? prevToken : await this.getToken();
const response = await fetch(`https://front-test.beta.aviasales.ru/tickets?searchId=${token}`);
if (response.ok) {
let tickets = await response.json();
***return tickets.tickets;***
} else if (response.status == '404') {
await this.getTickets();
} else {
await this.getTickets(token);
}
}
Каким образом это можно исправить? Примерно понимаю, что проблема возникает из-за растущего стека вызовов, но не хватает знаний, чтобы осилить этот момент.
Ответы (1 шт):
тогда продублирую для Вас ответ, что и в комментарии и отпишу в чём сок ошибки.
return this.getTickets(token) или return await this.getTickets(token).
здесь баг крылся в самом понимании js (в стеках вызовов), но он визуально незаметен, так что я случайно догадался.
когда Ваш первый вызов getTickets проходит неудачно, Вы заново вызываете getTickets. когда Ваш второй вызов getTickets закончился удачно, Вы возвращаете tickets обратно в результат первого getTickets. и получается вот такое:
if (!tickets.stop) {
await tickets; // результат выполненого второго getTickets, который уже никуда не возвращается (у него нет return)
} else {
return tickets.tickets;
}
затем стек вызовов заканчивается и Ваш первый getTickets должен закончиться, но он уже ничего не возвращает, так как Вы не указали, что результат tickets нужно вернуть. а так как первый getTickets ничего не возвращает, то по умолчанию его результат будет return undefined, как и у всех функциях, которые явно не указывают return.