Сбой TextDecoder в рекурсии ES6 Promise
Я пытаюсь запросить API, который отвечает с ReadableStream XML.
Код ниже использует рекурсивное обещание. Рекурсивный, потому что иногда он не декодирует поток в единственной итерации, и это вызывает мою головную боль.
Несмотря на то, что я успешно извлекаю данные, по какой-то причине этап декодирования иногда не завершается, что наводит меня на мысль, что поток слишком велик для одной итерации.
componentDidMount() {
fetch("http://thecatapi.com/api/images/get?format=xml&size=med&results_per_page=9")
.then((response) => {
console.log('fetch complete');
this.untangleCats(response);
})
.catch(error => {
this.state.somethingWrong = true;
console.error(error);
});
}
untangleCats({body}) {
let reader = body.getReader(),
string = "",
read;
reader.read().then(read = (result) => {
if(result.done) {
console.log('untangling complete'); // Sometimes not reaching here
this.herdingCats(string);
return;
}
string += new TextDecoder("utf-8").decode(result.value);
}).then(reader.read().then(read));
}
1 ответ
Я думаю, что следующую итерацию иногда вызывали до завершения текущей итерации, что приводило к неправильной конкатенации декодированного XML.
Я преобразовал функцию из синхронизации в асинхронную и как обычный рекурсивный метод компонента, а не как рекурсивное обещание с методом.
constructor({mode}) {
super();
this.state = {
mode,
string: "",
cats: [],
somethingWrong: false
};
}
componentDidMount() {
fetch("http://thecatapi.com/api/images/get?format=xml&size=med&results_per_page=9")
.then( response => this.untangleCats( response.body.getReader() ) )
.catch(error => {
this.setState({somethingWrong: true});
console.error(error);
});
}
async untangleCats(reader) {
const {value, done} = await reader.read();
if (done) {
this.herdingCats();
return;
}
this.setState({
string: this.state.string += new TextDecoder("utf-8").decode(value)
});
return this.untangleCats(reader);
}