В Javascript, как я могу прочитать несколько потоковых блоков из одного запроса API, используя fetch ()? - PullRequest
0 голосов
/ 08 мая 2019

В моем бэкэнде Node / Express у меня длинный (10 - 15 секунд) вызов API, который настраивает учетную запись пользователя.

Звонок вызывается из моего внешнего интерфейса с помощью простого fetch('my/api/url') запроса GET.

Я бы хотел иметь возможность отправлять сообщения внешнему интерфейсу / моему пользователю о состоянии запроса. («Настройка вашего профиля», «Загрузка ваших контактов», «Обработка данных» и т. Д. И т. Д.)

В моем экспресс-маршруте я (пытаюсь) отправить данные по:

exports.setupAccount = async () => {
   res.write("Getting contacts");

   // A bunch of code and async awaits
   // and when it's done...
   res.write(`Retrieved ${contacts.length} contacts!`);
}

Я сейчас пытаюсь понять API Mozilla Fetch () *1012* и даже не уверен, что смотрю в нужном месте.

В моем интерфейсе (пока просто ванильный JS) я делаю:

fetch('/my/setup/api')
.then(response => {
  const reader = response.body.getReader();
  reader.read().then(async ({ done, value }) => {
    console.log("VALUE", value); // <== This returns a Uint8Array
    var str = String.fromCharCode.apply(null, value);
    console.log("Message from API:", str);
  })
})

Это работает, но дает мне только first res.write(), отправленных с сервера, и не завершает последующие записи. Как мне прочитать несколько потоковых блоков, используя этот метод fetch / getReader()?

Ответы [ 2 ]

0 голосов
/ 08 мая 2019

Использование response.text() будет читать поток до завершения.Мы также можем использовать объект Response для извлечения других форматов, таких как BLOB-объекты (response.blob()) или JSON (response.json()).

fetch('/my/setup/api')
.then(response => response.text())
.then(text => console.log("Message from API:", text))
0 голосов
/ 08 мая 2019

Нашел ответ, который работает с vanilla JS, используя цикл while с await:

fetch('/my/api')
.then(async response => {
  const reader = response.body.getReader();

  while(true) {
    const {done, value} = await reader.read();
    // If it's done, there will be no value
    if (done) {
      console.log("Done!");
      break;
    }
    // value is Uint8Array of the chunk bytes
    var str = String.fromCharCode.apply(null, value);
    console.log(str)

  }
})
...