Почему response.json( ) после fetch асинхронен?

Во время работы с Fetch api возник вопрос, почему response.json( ) возращает промис? Мы ведь не посылаем никаких данных на сервер, просто нужно распарсить json, который мы получили в ответе от сервера. Для чего так было сделано? Объясните пожалуйста недалёкому
  • Вопрос задан
  • 780 просмотров
Пригласить эксперта
Ответы на вопрос 4
MvcBox
@MvcBox
Software Engineer [C/C++/JS(for Node.js)/etc]
Для чего так было сделано?

Все сделано логично и правильно. fetch() возвращает ответ как только все заголовки были прочитаны (не дожидаясь при этом получения полезной нагрузки). Если же надо получить и полезную нагрузку, то в ответе есть стрим, из которого уже читаете что Вам нужно (и сколько нужно).
Все остальные методы ( Response.json(), Response.text() и т.д ) являются просто хелперскими обертками над стримом и соответственно будут асинхронными.

Таким образом мы не делаем лишней работы и получаем тело ответа только в том случае, если оно нам действительно надо.
Ответ написан
Комментировать
sergiks
@sergiks Куратор тега JavaScript
♬♬
Посмотрите, как выглядит «текстовый чат» по протоколу HTTP, когда клиент запрашивает у сервера что-то, и получает ответ.

Примерная очерёдность:
Код на клиенте вызывает fetch(). Устанавливается соединение, передаётся запрос «дай /api/method» и передаются заголовки, типа «готов принять json».

Сервер обрабатывает, думает и «пишет в чат»:
1) Строку со статусом HTTP/1.1 200 OK – мол, норм, ща всё будет.
2) Несколько строк HTTP-заголовков ответа: размер, тип и пр.
Пустую строку – мол, заголовки всё.

Вот в этот момент fetch уже понимает, как у него дела с этим запросом. И ресолвит первый промис. Уже ясно, что вроде всё ок, ща польют данные, и это надолго. Дальше вступает в работу объект Response.

3) После пустой строки после заголовков ответа, сервер начинает лить данные тела ответа. Может пару букв, а может гигабайт дампа. Представьте медленный интернет, зарезанную скорость «недружественного» сайта и т.п.

Данные медленно ползут... И наконец, полностью переданы-получены.

Вот тут у объекта Response ресолвится его .json() промис. Посмотрите по ссылке — у того же объекта (мы его получаем после первого ресолва fetch()) есть и свойства, доступные сразу же, синхронно: например, объект с заголовками: свойство headers. Или свойство ok, значение которого следует из самой первой строки ответа сервера.

В общем, понять асинхронность помогает (мысленное) замедление всего и вся. Как будто интернет медленный, вычисления выполняются вручную на бумажке с калькулятором. Становится ясно, что какие-то потенциально долгие делишки ждать невесело, поэтому их делают асинхронными: сразу возвращают Promise, который отресолвится когда там всё доделается. А пока ждём, можно и салат оливье нарезать )
Ответ написан
Комментировать
yarkov
@yarkov Куратор тега JavaScript
Помог ответ? Отметь решением.
Мы ведь не посылаем никаких данных на сервер

По вашему получается, что асинхронной должна быть только передача и получение данных с сервера ))
Куча браузерного API работает асинхронно, используя промисы.
Конкретно про response.json( ). Ответ от сервера может быть весьма немаленьким и логично, что его чтение стоит сделать асинхронным. Но это моё предположение.
Ответ написан
Vindicar
@Vindicar
RTFM!
Потому что получение ответа от сервера - не то же самое, что получение контента. Скорее всего, мы получили только заголовки ответа, а в рамках соответствующих методов типа json() мы получаем тело ответа и парсим его.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы