Javascript Fetch использует код состояния более одного раза

Мне нужно найти способ, когда запрос получает 403, я могу использовать if перед вызовом JSON со статусом и данными. Только 403 возвращает HTML

const response = await fetch(
  // Fetch info
).then((response) => {
  if (!response.ok && response.status === 403) {
    // Stuffs
    throw new Error('Exception message'); // Raise error to stop the code
  }

  return response.json();
})
.then((data) => ({
  // I need use status code again, and keep the if statement 403 on top.
  status: response.status, 
  data,
}));

попробуйте { const response = await fetch(".."); console.info(ответ.статус); если(response.ok) вернуть response.json(); } catch(err) { /* проделайте здесь свою логику ошибки */}

Joel 21.10.2022 09:55

Не смешивайте синтаксис await и then, они не будут корректно работать при совместном использовании.

Jeremy 21.10.2022 09:58

@Jeremy "Эй, не ошибайся изящно при совместном использовании." что это вообще значит? Отказ от цепочки обещаний все равно вызовет исключение из await. Как обычно.

VLAZ 21.10.2022 10:00

@VLAZ Помимо прочего, Promises использует .then/.catch/.finally для обработки ошибок, а await использует try catch для обработки ошибок. Джереми совершенно прав в этом утверждении. Как можно вывести ошибку, генерируемую в предложении .then/.catch, во внешнюю область действия try catch?

Joel 21.10.2022 10:48

@ Джоэл То, как вы используете try/catch с await, требует отклонения обещания. try { await f() } catch (e) {} попадет в блок catch, если обещание от f() отклоняется. Механизма множественных ошибок нет — он всего один. В зависимости от состояния обещания. await либо продолжает выполнение обещания, либо вызывает исключение, которое переходит к блоку catch блока try/catch. Блок catch отражается обработчиком .catch(). Семантика API промисов соответствует try/catch для максимальной совместимости jsbin.com/jalahijuqa/1/edit

VLAZ 21.10.2022 11:06

@VLAZ почитайте здесь dev.to/maximization/… TLDR promises have a different error handling mechanism than async/await.

Jeremy 21.10.2022 12:02

@ Джереми, статья от кого-то, кто явно не понимает обещаний? Спасибо, мне это совсем не нужно. Мне нужно было только прокрутить до этого примера: i.imgur.com/Bgkq1YV.png правильный ответ — ни то, ни другое. Не совсем. Правильным кодом будет использование await Promise.update(), что затем сделает А. Б происходит потому, что вы не использовали await и не обработали отказ с помощью Promise.update().catch(). Это действительно так. Это не загадка. И это не какой-то жуткий дополнительный механизм. По сути, представьте, что вместо этого был Promise.reject("boom") - он явно не обрабатывается.

VLAZ 21.10.2022 12:20
Поведение ключевого слова "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
7
101
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Если вы хотите сохранить свой стиль .then(), а не переключаться на использование только await, вы можете просто переместить 2-й .then() туда, где у вас есть response в области видимости:

const result = await fetch(...).then((response) => {
    if (!response.ok && response.status === 403) {
        throw new Error('Exception message');
    }    
    return response.json().then(data => {
        status: response.status,
        data
    });
});

Или вы можете просто использовать await и избегать смешивания await и .then(), что обычно менее понятно и обычно его следует избегать:

const response = await fetch(...);
if (!response.ok && response.status === 403) {
    throw new Error('Exception message');
}
const data = await response.json();
const result = {status: response.status, data};

Обратите внимание: я избегал использования response в двух разных местах для обозначения двух разных вещей и использовал result для окончательного результата, а response оставил в качестве ответа fetch().

Не смешивайте async/await с .then/.catch, если у вас нет ОЧЕНЬ веской причины. В этом случае вы этого не сделаете.

Joel 21.10.2022 09:56

@ Джоэл, этот совет, чтобы избежать путаницы. Нет другой реальной причины избегать этого, кроме этого. И этот код не кажется запутанным.

VLAZ 21.10.2022 09:58

@ Джоэл - я уже предложил другой вариант, который их не смешивает. Микширование произошло из вопроса ОП, поэтому я просто показывал им, как адаптировать то, что у них было.

jfriend00 21.10.2022 09:58

@VLAZ Между ними большая разница. Обещание — это объект, представляющий промежуточное состояние операции, выполнение которого гарантированно завершится в какой-то момент в будущем. Async/Await — это синтаксический сахар для промисов, оболочка, делающая код более синхронным. то есть ждать ответа. Обещание имеет 3 состояния: разрешено, отклонено и ожидает выполнения. Асинхронное ожидание не имеет состояний. Он возвращает обещание, либо разрешенное, либо отклоненное. promise.then(fn) продолжает выполнение, пока await ожидает. Обработка ошибок .then() and .catch() и асинхронная try catch. я мог бы продолжить

Joel 21.10.2022 10:31

@ Джоэл, ты не описываешь никаких существенных различий. x = await f(); то же, что f().then(x => {}). Смешение двух концепций не только возможно, это буквально единственный способ работы кода, если вы когда-либо используете await. Бывают случаи, когда вы, вероятно, не хотите смешивать их — при чтении код будет более запутанным, чем нужно. Но просто сказать «они разные, потому что они используют разный синтаксис» — значит упустить лес за деревьями.

VLAZ 21.10.2022 10:36

@VLAZ "x = await f(); то же самое, что и f().then(x => {})" Нет, это не то же самое. Проверьте здесь простую демонстрацию: stackblitz.com/edit/js-ljkrwn?file=index.js

Joel 21.10.2022 10:41

@ Джоэл, ты пытаешься намеренно исказить мои слова? stackblitz.com/edit/js-mfbfvw?file=index.js Вы должны знать, что await построен на основе промисов. Вы уже сказали это с помощью «Async/Await — это синтаксический сахар для промисов», а затем внезапно дали мне то, что должно пройти как доказательство того, что два не работают одинаково, но вы используете код, который просто не пытается даже пытаться сделать тоже самое. Что вы тут пытаетесь возразить в конечном счете? Между async/await и promise API нет несовместимости.

VLAZ 21.10.2022 10:56

Люблю дружескую дискуссию, ребята. Вот почему не стоит их смешивать dev.to/maximization/…

Jeremy 21.10.2022 12:04

response является аргументом вашего первого обратного вызова, он не входит в область действия второго.

Будет намного проще, если вы прекратите использовать then (в общем, вряд ли когда-либо есть веская причина смешивать async/await и then):

const response = await fetch(/* fetch info */)
if (!response.ok && response.status === 403) {
  // Stuffs
  throw new Error('Exception message') // Raise error to stop the code
}
const data = await response.json()
const result = {
  status: response.status, 
  data
}

Я не. Вы отредактировали свой и дословно скопировали мой.

CherryDT 21.10.2022 10:07

Я не копировал твой.

jfriend00 21.10.2022 10:07

Видите, у нас было одно и то же (очевидное) решение, и мы одновременно печатали его :)

CherryDT 21.10.2022 10:08

...и если вы мне не верите, вы можете проверить временные метки. Я ответил в 07:57:18 и вы добавили решение в редактирование своего ответа в 07:58:19, через одну минуту и ​​​​одну секунду.

CherryDT 21.10.2022 10:16

Это... очень тривиальное и прямолинейное преобразование от промисов к просто await синтаксису. В итоге вы получите в основном тот же код. И имена переменных полностью общие и очень распространены для этих случаев использования. Так что я не думаю, что это было скопировано.

VLAZ 21.10.2022 10:27

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