Извлечение данных из ReadableStream с помощью Fetch API
Быстрый ответ
Для того чтобы получить данные из ReadableStream
, примените методы getReader()
и read()
:
const reader = stream.getReader();
let chunks = [], decoder = new TextDecoder();
reader.read().then(function processData({ done, value }) {
if (done) {
console.log('Поток завершён, все фрагменты данных получены', decoder.decode(concat(chunks)));
return;
}
chunks.push(value);
reader.read().then(processData);
});
function concat(chunks) { // Объединяем части в одно целое
return chunks.reduce((acc, chunk) => new Uint8Array([...acc, ...chunk]), new Uint8Array());
}
Используя этот код, вы будете рекурсивно вызывать read()
, собирать обрывки данных и в конечном итоге, декодировать и выводить собранные данные.
Использование Fetch API с ReadableStream
Для выполнения API-запросов используйте метод fetch()
. Чтобы обработать JSON используйте response.json()
, для текстовых данных — response.text()
, а для бинарных данных — response.arrayBuffer()
.
fetch('https://api.example.com/data')
.then(response => response.json()) // Преобразуем ответ в JSON
.then(data => console.log(data))
.catch(error => console.error('Произошла ошибка:', error));
// Обработка данных в формате, отличном от JSON
fetch('https://api.example.com/data')
.then(response => response.text()) // Получаем текстовую информацию
.then(text => console.log(text))
.catch(error => console.error('Произошла ошибка:', error));
// Работа с бинарными данными
fetch('https://api.example.com/binary-data')
.then(response => response.arrayBuffer()) // Получаем массив байт
.then(buffer => console.log(new Uint8Array(buffer)))
.catch(error => console.error('Произошла ошибка:', error));
Интересно, что response.json()
, response.text()
и response.arrayBuffer()
сами справляются с задачей собирания и декодирования данных.
Ручной парсинг ReadableStream для смельчаков
Парсинг ReadableStream
вручную — это настоящее приключение. Воспользуйтесь getReader()
для чтения данных. TextDecoder
придёт вам на помощь в сборке и декодировании.
async function streamToString(stream) {
const reader = stream.getReader();
const decoder = new TextDecoder(); // Наш помощник — декодер
let result = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
result += decoder.decode(value, { stream: true });
}
result += decoder.decode(); // Финальный шаг для получения данных
return result;
}
streamToString(yourReadableStream)
.then(str => JSON.parse(str))
.then(data => console.log('Данные получены:', data))
.catch(error => console.error('Ошибка при обработке данных:', error));
Управление ошибками и путь менее избитый
Всегда реализуйте обработку ошибок с помощью catch()
. Экспериментируйте с разнообразными методами декодирования и создавайте собственные парсеры для работы с нестандартными типами данных.
fetch('https://api.example.com/data').then(response => {
if (!response.ok) {
throw new Error('Сервер вернул некорректный ответ');
}
return response.json();
})
.catch(error => {
console.error('Произошла ошибка при запросе данных:', error);
});
Node.js работает иначе, предлагая stream
и современный API stream/consumers
для эффективной работы с потоками. Обратите внимание на TransformStream
для преобразования данных, а также на поточные пайплайны.
Визуализация
Ваши действия с ReadableStream
можно сравнить с игрой в ведро и кран.
Когда вы открываете "кран" с помощью stream.getReader()
...
const reader = stream.getReader();
reader.read().then(({ value, done }) => {
if (done) {
console.log("Поток завершён. Данные собраны!");
} else {
console.log(`Получена новая порция данных:`, value);
}
});
... и затем закрываете его:
reader.cancel(); // Прерываем чтение данных из потока.
Теперь все данные собраны и их можно использовать по вашему усмотрению.
Полезные материалы
- Использование потоков чтения – Веб-API | MDN — полное руководство по ReadableStreams.
- ReadableStream – Веб-API | MDN — детальная информация о ReadableStream.
- GitHub – whatwg/streams: Стандартные потоки — ресурс по стандартам потоков.
- 2016 — год веб-потоков – JakeArchibald.com — статья Джейка Арчибальда о потоках.
- Потоки для немедленной передачи данных | Блог | Chrome для разработчиков — примеры использования потоков от Google.
- Потоки: полное руководство | Статьи | web.dev — доступное руководство по потокам.