получить response.status в. затем в Java Script - PullRequest
1 голос
/ 30 мая 2020

Я попытался проверить, имеет ли статус моего запроса 200 (ОК), но я не знаю, как это сделать вместе, потому что первый и второй .then не «похожи друг на друга»:

function f(path) {
    await fetch(path)
            .then(response => {
                // console.log(response.status);
                if (response.status != 200) {
                    throw response.status;
                } else {
                    // do something
                }
            })
            .then(response => response.json())
            .then(...method for the response.json()...)
            .catch(error => {
                // print some error message
            }
}
  • Второй отказал и вернул ошибку.

У меня проблема, когда я его бросаю.

Сообщение об ошибке выводится на консоль ( когда я проверяю, изменяя путь на неправильный, и хочу посмотреть, исправляю ли я ошибки).

что я могу сделать?

Ответы [ 5 ]

1 голос
/ 30 мая 2020

Собственно, непонятно, что должна делать ваша функция. Но я думаю, что ваша проблема связана с непониманием того, как работает цепочка обещаний. Для этого я бы рекомендовал ознакомиться с этой статьей, она мне очень помогла :)

Итак, вернемся к вашей функции. Элегантным решением является добавление простой функции «касания», которая позволяет вам делать некоторые вещи с текущим ответом, но при этом передает ответ дальше для других цепочек .then.

Вот функция касания:

const tap = (callback) => (value) => (callback(value), value);

И напоследок как можно его использовать:

async function f(path) {
  await fetch(path)
    .then(
      tap((response) => {
        if (response.status !== 200) throw new Error(response.status);
      })
    )
    .then((response) => {
      // do other stuff
    })
    .catch((error) => console.error(error));
}
1 голос
/ 30 мая 2020

Вам нужно вернуть в цепочке then, что на первый взгляд кажется слишком большим. Посмотрите следующий пример ...

fetch(path)
  .then(r => r.ok ? r.json() : Promise.reject('oops')) // .statusText, etc
  .then(r => {
    // [...]
  })
  .catch(e => console.error(e)); // oops
1 голос
/ 30 мая 2020

a) Я не думаю, что вам нужно ключевое слово await, поскольку вы используете цепочку .then ().

b) Вы должны вернуть что-то из первого, а затем, чтобы получить это в следующем .then ()

function f(path) {
await fetch(path)
        .then(response => {
            // console.log(response.status);
            if (response.status != 200) {
                throw response.status;
            } else {
                // do something
                 // After doing what you need return the response
                return response
            }
        })
        .then(response => response.json())
        .then(...method for the response.json()...)
        .catch(error => {
          // print some error message
          }
}
1 голос
/ 30 мая 2020

Вы правильно проверяете это в своем первом обработчике выполнения (then обратный вызов), хотя я бы просто использовал !response.ok. Обычно вам не нужен статус в последующих обработчиках.

Но проблема с вашим первым обработчиком выполнения заключается в том, что он ничего не возвращает, поэтому последующий обработчик выполнения видит только undefined. Вместо этого верните обещание из json():

function f(path) {
    fetch(path)
        .then(response => {
            if (!response.ok) {
                // Note: Strongly recommend using Error for exceptions/rejections
                throw new Error("HTTP error " + response.status);
            }
            return response.json();
        })
        .then(data => {
            // ...use the data here...
        })
        .catch(error => {
            // ...show/handle error here...
        });
}

Обратите внимание, что вы не можете использовать await в традиционной функции, только в функции async. Но вам это не нужно, если вы используете .then и .catch. Я удалил его выше.

Если по какой-то причине вам нужен статус в последующих обработчиках выполнения, вам придется вернуть его из первого обработчика выполнения. Например:

function f(path) {
    fetch(path)
        .then(response => {
            if (!response.ok) {
                // Note: Strongly recommend using Error for exceptions/rejections
                throw new Error("HTTP error " + response.status);
            }
            return response.json().then(data => ({status: response.status, data}));
        })
        .then(({status, data}) => {
            // ...use `status` and `data` here...
        })
        .catch(error => {
            // ...show/handle error here...
        });
}

В этом случае я использовал вложенный обработчик выполнения для обещания из json(), а затем вернул объект с status и data на нем.

0 голосов
/ 01 июня 2020

Количество браузеров, которые поддерживают fetch, но не поддерживают async / await, сейчас очень мало, поэтому вам может быть лучше сначала использовать этот более простой синтаксис, а затем транспилировать для устаревших браузеров вместе с вашим прокладки для fetch.

Ваша функция становится:

try {
    const response = await fetch(path);

    // console.log(response.status);
    if (response.status != 200) {
        throw response.status;
    } else {
        // do something
    }

    const parsed =  await response.json();

    // do something with parsed
}
catch(error) {
    // print some error message
}

Этот новый синтаксис значительно упрощает работу с ошибками в различных действиях then:

const response = await fetch(path);

// console.log(response.status);
if (response.status != 200) {
    throw response.status;
} else {
    // do something
}

let parsed; // Will hold the parsed JSON
try {    
    parsed =  await response.json();
}
catch(error) {
    // Deal with parsing errors
}

try {
    // do something with parsed
}
catch(error) {
    // Deal with errors using the parsed result
}
...