API Javascript Fetch с обещаниями – передача кода ответа HTTP

Я использую следующий код для отправки HTTP-запросов к моему API:

fetch('api/register', {
    method: 'POST',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify(jsonObj)
})
    .then(response => {
        responseClone = response.clone();
        if (!response.ok) {
            console.info(`HTTP ERROR STATUS CODE: ${response.status}`);
        }
        return response.json();
    })
    .then(function (data) {
        processDataFromServer(data);
    }, function (rejectionReason) {
        console.info('JSON Parsing Error:', rejectionReason, responseClone);
        responseClone.text()
            .then(function (bodyText) {
                console.info('Cannot parse as JSON:', bodyText);
            });
    })
    .catch(error => {
        console.info("Error: " + error)
        deplayError(error);
    });

Код работает! Единственное изменение, которое я хочу сделать, это передать response.status моей processDataFromServer(data) функции. Что-то вроде processDataFromServer(data, response.status). Поскольку response.json() — это обещание, я не могу одновременно вернуть обещание и свойство в следующий метод. Есть идеи, как это можно сделать?

processDataFromServer(await response.json(), response.status)?
jonrsharpe 01.07.2024 19:01

Реорганизуйте это, используя async и await, и это будет проще.

Barmar 01.07.2024 19:03
Поведение ключевого слова "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) для оценки ваших знаний,...
0
2
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Будет проще, если вы перепишете свой код как функцию async и будете использовать await. Что-то вроде этого:

async function retrieve() {
    try {
        const response = await fetch('api/register', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(jsonObj)
        });
        const responseClone = response.clone();
        if (!response.ok) {
            console.info(`HTTP ERROR STATUS CODE: ${response.status}`);
        }
        try {
            const data = await response.json();
            processDataFromServer(data, response.status);
        } catch (rejectionReason) {
            console.info('JSON Parsing Error:', rejectionReason, responseClone);
            const bodyText = await responseClone.text();
            console.info('Cannot parse as JSON:', bodyText);
        }
    } catch (error) {
        console.info("Error: " + error)
        deplayError(error);
    }
}

retrieve();

Без async

Как вы упомянули в комментариях, что хотели бы придерживаться цепочки .then, вот альтернатива:

Вы можете объединить обещание response.json() с response.status в массиве и передать его Promise.all. Это будет относиться как к данным, так и к статусу.

Итак, измените это:

return response.json();

К:

return Promise.all([response.json(), response.status]);

И получите разрешенные значения в следующем обратном вызове then, изменив это:

.then(function (data) {

К:

.then(function ([data, status]) {

...и теперь у вас есть доступ к status для звонка на processDataFromServer.

ваше предложение правильное. Но я не использовал async/await в своем проекте, и для последовательности я хотел бы придерживаться этого (если кто-то не убедит меня, что этого невозможно достичь, просто используя обещания).

PC. 01.07.2024 19:39

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

trincot 01.07.2024 19:41

Смотрите дополнение к ответу.

trincot 01.07.2024 19:48

Это потрясающе!

PC. 01.07.2024 19:50

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