Как можно реализовать читаемый поток в клиенте JS, если обещание получения разрешается только после получения всех данных - PullRequest
0 голосов
/ 25 апреля 2020

Я видел во многих местах явно работающий код, который позволяет клиенту браузера извлекать URL-адрес и получать ответ «как это происходит» - кусками. Но хотя он с радостью будет работать в wget (и я предполагаю, что curl тоже), я просто не могу заставить его работать на клиенте JS на chrome или firefox.

на сервере ( Экспресс / маршрутизатор) работает следующим образом:

router.post('/', async (req, res, next) => {
  res.writeHead(200, {
    'Connection'             : 'Transfer-Encoding',
    'Content-Type'           : 'text/plain; charset=utf-8',
    'Transfer-Encoding'      : 'chunked',
    'X-Content-Type-Options' : 'nosniff',
  });
  res.flushHeaders();
  res.write('here is some stuff\n');
  await sleep(5000);
  res.write('here is some more stuff\n');
  await sleep(5000);
  res.write('and we are done');
  res.end();
}

И код клиента:

const response = await fetch('/api/test', {
  method    : 'POST',
  headers   : { 'Content-Type': 'text/plain;charset=UTF-8' },
});
console.log('response awaited');  // <-- this never fires until the response is complete
const reader = response.body.getReader();
while(true) {
  const { done, value } = await reader.read();
  console.log(`Received ${value} value`);
  if (done) break;
}

Проблема заключается в том, что console.log после ответа await не запускается для около 10 секунд - то есть время, которое потребовалось мне для полного ответа. Другими словами, обещание ответа просто не разрешается до тех пор, пока весь ответ не будет готов, и к этому моменту материал body / getReader / reader.read, который следует, является пустой тратой времени - ответ уже выполнен и очищен!

Насколько я понимаю, ответное обещание должно разрешиться, как только заголовки будут получены ... и мой сервер устанавливает заголовки и мгновенно сбрасывает их, прежде чем что-либо делать ... но нет, обещание занимает полные 10 секунд или так, чтобы решить, так что это явно не происходит. И с этим обещанием, не разрешенным до тех пор, пока все не закончится, как кто-нибудь может заставить работать эти читаемые потоки?!

Я также попытался использовать get вместо post и реализовать выборку в xhr, но получил точно такое же поведение. Кто-нибудь может заметить, что я делаю что-то не так?

...