Сбой 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);
}
Другие вопросы по тегам