Я использую следующий код для отправки 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()
— это обещание, я не могу одновременно вернуть обещание и свойство в следующий метод. Есть идеи, как это можно сделать?
Реорганизуйте это, используя async
и await
, и это будет проще.
Будет проще, если вы перепишете свой код как функцию 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 в своем проекте, и для последовательности я хотел бы придерживаться этого (если кто-то не убедит меня, что этого невозможно достичь, просто используя обещания).
Думаю, я понимаю, что вы имеете в виду, но в этом коде также хорошо используются обещания. Я думаю, вы имеете в виду, что по какой-то причине не хотите использовать async
?
Смотрите дополнение к ответу.
Это потрясающе!
processDataFromServer(await response.json(), response.status)
?