Express.js: отправить ответ частями

Можно ли на Express.js отправить ответ порцией данных? Я пробовал (онлайн-демо):

const express = require('express');
const app = express();
const port = 3111;

const sleep = (ms) => {
  return new Promise((resolve) => setTimeout(resolve, ms));
};

app.get('/', async (req, res) => {
  res.setHeader('Content-Type', 'application/json');
  // flush to enable stream
  res.flushHeaders();
  res.write('[');
  for (let i = 1; i <= 1000; i++) {
    res.write(JSON.stringify(`data ${i}`));
    if (i + 1 <= 1000) {
      res.write(',');
    }
    await sleep(1);
  }
  res.write(']');
  res.end();
});

app.listen(port, () => {
  console.info(`App is live at http://localhost:${port}`);
});

Но и в Google Chrome, и в Postman ответ отображается только при вызове res.end().

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Есть некоторые соображения

  1. Вам следует добавить правильный Content-Type для таких потоков, как application/stream+json.
  2. Имейте в виду, что браузеры и некоторые HTTP-клиенты могут буферизовать ответ (они не будут отображать фрагменты по мере их поступления, а вместо этого будут ждать, пока не получат весь ответ), поэтому вам, возможно, придется рассмотреть возможность использования JavaScript для обработки ответа.
  3. Вам не нужен res.flushHeaders(), поскольку Express автоматически обрабатывает его, когда вы начинаете писать тело ответа.
import express from "express";
const app = express();

const sleep = (ms) => {
    return new Promise((resolve) => setTimeout(resolve, ms));
};

app.get('/stream', async (_req, res) => {
    res.setHeader('Content-Type', 'application/stream+json');

    res.write('[');
    for (let i = 1; i <= 1000; i++) {
        res.write(JSON.stringify(`data ${i}`));
        if (i < 1000) {
            res.write(",");
        }
        await sleep(1); // Simulates a delay
    }
    res.write(']');
    res.end();
});

const port = 3000;
app.listen(port, () => {
    console.info(`Server running on http://localhost:${port}`);
});

При использовании netcat темп возвращаемых данных кажется правильным, и это фрагмент закодирован.

echo -ne 'GET /stream HTTP/1.1\n\n' | netcat localhost 8080

Пример вывода:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json
Date: Mon, 06 May 2024 08:58:26 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked

1
[
8
"data 1"
1
,
8
"data 2"
1
,
8
"data 3"
1
,
8
"data 4"

Другие вопросы по теме

Создайте базовый сервер, используя NodeJS, Express, TypeScript, и выполните следующие действия в отдельных API соответственно в том же файле app.ts
Как скомпоновать статическое фоновое изображение и gif с помощью пакета Sharp nodejs
Имитация ответа на выбор AWS S3 с помощью Jest и AWS SDK V3
Ошибка типа: Tasks.map не является функцией (стек MERN)
Проблемы с Corepack и Yarn — нить init -2 завершается с ошибкой запроса
Контейнер Docker выходит из строя после предупреждения «Использование eval в «node_modules/three-stdlib/libs/lottie.js» настоятельно не рекомендуется»
Не удалось выполнить нагрузочный тест сервера Nginx (приложение Node.js)
Как обрабатывать request.body имеет значение null, которое отправляется клиентом в node.js express?
Использование составной функции пакета node js Sharp не дает анимированного результата
Токен идентификатора Firebase имеет неверное утверждение "audi" (аудитория). Ожидал XXX, а получил XXX